Change the XPath-root of an XmlDocument in .net (C#)?
When selecting from an XmlDocument by e.g. the XPath-method SelectSingleNode we get an XmlNode that consist of the first matching node, lets call it <node1>. If we do further selection on <node1> then one might expect that the XPath-root now is this node, but this is incorrect, the root is still the same as in the original XmlDocument开发者_运维知识库. Here's an example:
XmlDocument xd = new XmlDocument();
xd.LoadXml(@"<root>
<subroot>
<elm>test1</elm>
<elm>test2</elm>
<elm>test3</elm>
</subroot>
</root>");
XmlNode xnSubRoot = xd.SelectSingleNode("/root/subroot");
//This is the XPath I want to be able to use, but it returns null.
XmlNode xnElm = xnSubRoot.SelectSingleNode("/subroot/elm");
//This works, but the XPath-root is the same as in the original document.
xnElm = xnSubRoot.SelectSingleNode("/root/subroot/elm");
Is there any way to "fix" the root of xnSubRoot so that I can use the XPath I want? The reason for my question is because I have a case where I'm calling a webservice that returns an XmlNode where the OuterXml-property shows a structure of "/Data/SubElement/..." and so on, but when running XPath "/Data" then null is returned, only "/SubElement" works, i.e. the XPath-root seems to be one level lower than the actual document-root.
I'm sure there is a perfectly reasonable explanation for this, or that I'm missing something vital. However I really can't seem to find anything, even though I've read http://msdn.microsoft.com/en-us/library/d271ytdx(VS.80).aspx.
N.B. I do realize that it would be possible to use the XPath "//subroot/elm", but then I might also get other elements further down in the XML structure.
Since your selecting from the Root/SubElement
Try this:
XmlNode xnElm = xnSubRoot.SelectSingleNode("elm");
It will return the first child elm
node of the current node.
Edit (from additionals informations provided in comments):
In this specific case, you are obtaning a XmlNode
(which is your Data node) from a WebService call. All XPath requests on that XmlNode
will be relative to it.
I would suggest that you modify all your XPaths to use a selector like webServiceNode.SelectSingleNode("SubElement/SubSubElement");
. There is no reason to specify absolute XPaths queries here.
This works:
XmlNode xnSubRoot = xd.SelectSingleNode("/root/subroot");
XmlNode xnElm = xnSubRoot.SelectSingleNode("elm");
And so does this:
XmlNode xnRoot = xd.SelectSingleNode("/root");
XmlNode xnElm = xnRoot.SelectSingleNode("subroot/elm");
精彩评论