martin martin - 9 months ago 65
C++ Question

MSXML C++ Declare default namespace

I'm using Visual Studio C++ with MSXML imported (#import "msxml6.dll") to create xml documents using the smart pointers.

I use the setProperty() function to create the namespaces and I then add the corresponding attributes to the document element but when I try to declare a default namespace all of the elements below the document element have the attribute

added to them.

Here is my code:

// Macro to check HRESULT
#define CheckHr(myHr) do{ hr = myHr; if(FAILED(hr)) throw _com_error(hr); }while(0)

void makeMyXml()
MSXML2::IXMLDOMDocument3Ptr xDoc{ NULL };

// Create document

// Add namespaces
CheckHr(xDoc->setProperty(L"SelectionNamespaces", _T("xmlns=\"http://myDefaultNamespaceURL\" xmlns:xsi=\"\"")));

// Add document element

// Add namespace attributes to root
CheckHr(xDoc->GetdocumentElement()->setAttribute(_T("xmlns"), _T("http://myDefaultNamespaceURL")));
CheckHr(xDoc->GetdocumentElement()->setAttribute(_T("xmlns:xsi"), _T("")));
CheckHr(xDoc->GetdocumentElement()->setAttribute(_T("xsi:schemaLocation"), _T("http://schemaLocationValue")));



catch (_com_error &e)
// handle any thrown com errors here


The xml this creates looks like this:

<root xmlns="http://myDefaultNamespaceURL" xmlns:xsi="" xsi:schemaLocation="http://schemaLocationValue">
<exampleElement xmlns=""/>

I haven't been able to find a way to just have
instead of
<exampleElement xmlns=""/>

Answer Source

With MSXML, to create elements or attributes in a namespace, you need to use the createNode method where you use e.g. xDoc->createNode(1, "root", "http://myDefaultNamespaceURL") to create an element in the namespace http://myDefaultNamespaceURL. Make sure you use the same for all descendant elements you want to put in the same namespace. You can also use createNode to create attributes in a namespace e.g. createNode->(2, "xsi:schemaLocation", "") and then add that to the attributes of the element.

The W3C DOM in level 2 and 3 has namespace aware createElementNS and setAttributeNS to be used in case of XML with namespaces but the MSXML API dates from before those levels and was never updated to match the W3C DOM, its only namespace aware method is createNode. The methods createElement and setAttribute are basically only useful to create XML without namespaces.

See also which uses JScript with MSXML but obviously the problem and solution relating to proper API use is the same.