是否在.net(C#)中更改XmlDocument的XPath根?

是否在.net(C#)中更改XmlDocument的XPath根?,c#,.net,.net-2.0,xmldocument,xpath,C#,.net,.net 2.0,Xmldocument,Xpath,当通过XPath方法SelectSingleNode从XmlDocument中进行选择时,我们得到一个由第一个匹配节点组成的XmlNode,让我们调用它。如果我们在上做进一步的选择,那么人们可能会认为XPath根现在就是这个节点,但这是不正确的,根仍然与原始XmlDocument中的根相同。下面是一个例子: XmlDocument xd = new XmlDocument(); xd.LoadXml(@"<root> <subroot>

当通过XPath方法SelectSingleNode从XmlDocument中进行选择时,我们得到一个由第一个匹配节点组成的XmlNode,让我们调用它。如果我们在上做进一步的选择,那么人们可能会认为XPath根现在就是这个节点,但这是不正确的,根仍然与原始XmlDocument中的根相同。下面是一个例子:

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");
XmlDocument xd=新的XmlDocument();
xd.LoadXml(@)
测试1
测试2
测试3
");
XmlNode xnSubRoot=xd.SelectSingleNode(“/root/subroot”);
//这是我希望能够使用的XPath,但它返回null。
XmlNode xnElm=xnSubRoot.SelectSingleNode(“/subroot/elm”);
//这是可行的,但XPath根目录与原始文档中的相同。
xnElm=xnSubRoot.SelectSingleNode(“/root/subroot/elm”);
有没有办法“修复”xnSubRoot的根,以便使用我想要的XPath?我问这个问题的原因是因为我调用了一个webservice,它返回一个XmlNode,其中OuterXml属性显示“/Data/SubElement/…”等结构,但当运行XPath“/Data”时,返回null,只有“/SubElement”起作用,也就是说,XPath根似乎比实际文档根低一级

我肯定有一个完全合理的解释,或者说我遗漏了一些重要的东西。然而,即使我读过,我似乎真的找不到任何东西


注意:我确实意识到可以使用XPath“//subroot/elm”,但是我也可能会在XML结构中获得更深层的其他元素。

因为您从
根/子元素中选择了
,请尝试以下操作:

XmlNode xnElm = xnSubRoot.SelectSingleNode("elm"); 
它将返回当前节点的第一个子
elm
节点

编辑(来自评论中提供的附加信息):

在这种特定情况下,您将从WebService调用中获得一个
XmlNode
(即您的数据节点)。该
XmlNode
上的所有XPath请求都将与之相关

我建议您修改所有XPath,以使用类似于
webServiceNode.SelectSingleNode(“SubElement/SubSubElement”)的选择器。没有理由在此处指定绝对XPath查询。

这可以:

XmlNode xnSubRoot = xd.SelectSingleNode("/root/subroot");
XmlNode xnElm = xnSubRoot.SelectSingleNode("elm");
这也是:

XmlNode xnRoot = xd.SelectSingleNode("/root");
XmlNode xnElm = xnRoot.SelectSingleNode("subroot/elm");

谢谢,说到我举的例子,你当然是对的。但是,当XPath根实际上低于文档根时,情况会怎样呢?我不确定这是怎么回事,但我从webservice收到的XMLNode就是这样。您收到的XMLNode没有父节点,这导致了您看到的行为。每个节点仅使用InnerXml属性显示的结构。如果您想在示例中实现同样的效果,可以执行
xnSubRoot=xnSubRoot.CloneNode(true)
。这可能不是最好的解决方案,但至少它似乎有效。不过,我想知道为什么要使用基于根的XPath查询(即以“/”开头)?谢谢,在我给出的示例中,您当然是对的。但是,当XPath根实际上低于文档根时,情况会怎样呢?我不确定这是怎么回事,但我从web服务收到的XMLNode就是这样。您能提供web服务Xml的示例吗?我使用VS2005中的“添加web引用”功能自动生成调用web服务的代码。此代码调用System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(字符串,对象[]),它返回对象[],然后将对象[0]显式类型转换为XmlNode。关于XML,很抱歉,我不能在这里显示它,但是文档结构是。但是,当在其上运行XPath时,根是/SubElement,而不是预期的/Data(即SelectSingleNode(“/Data”)返回null,但SelectSingleNode(“/SubElement”)可以工作)。我仍然不确定,在我使用webservice的情况下,绝对XPath为什么不从与OuterXml中的document元素相同的元素开始,而是在一个较低的层次上。无论如何,感谢你们两位的提示,使用相对路径而不是绝对路径。关于SelectNode方法,我想说的是关于您正在查询的对象。请记住,执行SelectNode查询可搜索(当前对象的)特定子对象。