selectNodes does not give node list when xmlns is used
hello ,
I am trying to use IXMLDOMDocument's selectNodes method to get the node list based upon xpath expression.
I am passing the xpath expression in the method, but the node list returned is empty.
however if I remove the xmlns attribute from the root node then i get the correct number of nodes(which is 2) .
Here is my sample xml :
<?xml version="1.0" encoding="UTF-16"?>
<buttonViewer name="Code" setupPath="Applications.App1.Program1" loop="true" xmlns="buttonViewerSchema1_0">
<buttonViewerSetup stepElapsedTime="0" controllerType="AC800M"/>
<buttonStep stepName="S1" stepId="1" channel="1" initialStep="1">
<ObjectPosition posX="1" posY="1"/>
</buttonStep>
<buttonStep stepName="S2" stepId="2" channel="1" initialStep="1">
<ObjectPosition posX="1" posY="2"/>
</buttonStep>
</buttonViewer>I am using the following code in VC++ (VS2005)
BSTR searchitem = NULL;
IXMLDOMNodeList *pNodes=NULL;
CComQIPtr<IXMLDOMDocument> pDOM(pDoc);
searchitem = SysAllocString(L"//buttonStep");
hr = pDOM->selectNodes(searchitem, &pNodes);
if (pNodes)
{
long length=0;
hr = pNodes->get_length(&length);
}the length value is retuned as 0 after calling pNodes->get_length(), hr value is S_OK.
I can not change XML and also I am not sure about the use of xmlns="buttonViewerSchema1_0" as my application is not validating the xml against any xsd.
Answers
- With XPath 1.0 you need to bind a prefix to that namespace URI and use that prefix in XPath expressions, with MSXML to bind a prefix you need to call the setProperty method of the document object with first argument "SelectionNamespaces" and second argument e.g. "xmlns:pf='buttonViewerSchema1_0'", then use an XPath expression alike "//pf:buttonStep".
All Replies
- With XPath 1.0 you need to bind a prefix to that namespace URI and use that prefix in XPath expressions, with MSXML to bind a prefix you need to call the setProperty method of the document object with first argument "SelectionNamespaces" and second argument e.g. "xmlns:pf='buttonViewerSchema1_0'", then use an XPath expression alike "//pf:buttonStep".
Hello Martin,
Thanks for your reply. It worked.
Thanks again,we just encountered this problem too. the XPath expression worked fine in XMLSpy, but not in .NET
eg
XmlNodeList nodeList = doc.SelectNodes("//element");
the solution was as you say, add the namespace eg "http://yournamespace/" from the top of the xml doc to an XmlNamespaceManager
eg
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
namespaceManager.AddNamespace("pf", @"http://yournamespace/");
then to select the elements named "element"
eg
XmlNodeList nodeList = doc.SelectNodes("//pf:element", namespaceManager);Perhaps MS could make this easier for developers, a 2 min job turned into a hour of searching Google.
Further to bamboowave's solution, you can use this to pick up the namespace dynamically so you don't have to hardcode it:
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
namespaceManager.AddNamespace("pf", doc.DocumentElement.NamespaceURI);
bamboowave wrote: Perhaps MS could make this easier for developers, a 2 min job turned into a hour of searching Google.
+1. The "old" way should work as well. Wasted precious time.


