I'm trying to parse a valid XML document in c# .NET using xPathNavigator
. The start of the XML document looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:myResponse xmlns:ns1="ExampleNS" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<myReturn href="#2" />
As you can see, there's some namespaces defined on the root element, but then ns1
is defined later on. When I try and evaluate an xPath query /soapenv:Envelope/soapenv:Body/ns1:myResponse/myReturn
I get an XPathException
:
Namespace prefix 'ns1' is not defined.
What I'm doing is getting the XML document as a string, loading it into an XmlDocument
object. Then I'm creating a navigator, moving to the root element and calling GetNamespacesInScope(XmlNamespaceScope.All)
. I loop through this collection, which contains the namespaces for xml
, soapenv
, xsd
and xsi
as defined on the root, adding them to the namespacemanager. Then I create an xPathNavigator
and call Evaluate
, and get the exception.
Code is this:
string response = GetXMLString();
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(response);
var xmlDocumentNavigator = xmlDocument.CreateNavigator();
xmlDocumentNavigator.MoveToFollowing(XPathNodeType.Element);
var xnm = new XmlNamespaceManager(xmlDocument.NameTable);
var namespacesInScope = xmlDocumentNavigator.GetNamespacesInScope(XmlNamespaceScope.All);
if (namespacesInScope != null)
{
foreach (var prefix in namespacesInScope.Keys)
{
xnm.AddNamespace(prefix, namespacesInScope[prefix]);
}
}
var xPathDocument = new XPathDocument(new StringReader(response));
var xPathNavigator = xPathDocument.CreateNavigator();
xPathNavigator.Evaluate("/soapenv:Envelope/soapenv:Body/ns1:myResponse/myReturn", xnm);
Why doesn't the GetNamespacesInScope
method pick up on ns1
?