I have an xml string such as this:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ExecuteResponse xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
<ExecuteResult i:type="a:RetrieveEntityResponse" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ResponseName>RetrieveEntity</a:ResponseName>
<a:Results xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
<a:KeyValuePairOfstringanyType>
<b:key>Some Value</b:key>
</a:KeyValuePairOfstringanyType>
</a:Results>
</ExecuteResult>
</ExecuteResponse>
</s:Body>
</s:Envelope>
I’m trying to do something along the lines of:
var resolver = xmlDoc.createNSResolver(xmlDoc.documentElement);
return new XPathEvaluator().evaluate("//b:key", xmlDoc.documentElement, resolver, XPathResult.ANY_TYPE, null);
The key node is not being found, and the reason is when I call
resolver.lookupNamespaceURI("b")
directly, it returns null. However, it does return something when I do
resolver.lookupNamespaceURI("s")
so my best guess is the createNSResolver method only looks for namespaces in the root node of the xml document that is passed in. Is there any way to make it find all of the namespaces that are defined in the xml, or some other way to build a list of all of the namespaces that exist in the document?
Thanks!
Well setting up consistent namespace resolving based on all namespace declarations in the XML document is not possible in the general case as you could have e.g.
where the same namespace is used with different prefixes and of course you could have samples as e.g.
where the same prefix is bound to different namespace URIs on different elements.
So basically you need to know the namespace URI of the element node you are looking for, then you can set up a namespace resolver with any prefix your code can choose e.g.
On the other hand with that simple path I would not use XPath and
evaluateat all but rather go forreturn xmlDoc.getElementsByTagNameNS('http://schemas.datacontract.org/2004/07/System.Collections.Generic', 'b');.As for finding namespace declarations in a DOM tree to build up a namespace resolver yourself based on prefixes, XPath can give some assistance itself by looking at the namespace axis e.g.
//namespace::*but inside the browser Mozilla/Firefox never considered it necessary to support the namespace axis. Then there are some DOM Level 3 methods http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix and http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI so you could write your own code walking the DOM tree and collecting namespace declarations but that does not help in the general case to solve the problems outlined in the two example samples I posted above.