XPath和选择单个节点
时间:2020-03-05 18:43:00 来源:igfitidea点击:
我正在使用.NET中的XPath来解析XML文档,大致情况如下:
XmlNodeList lotsOStuff = doc.SelectNodes("//stuff"); foreach (XmlNode stuff in lotsOStuff) { XmlNode stuffChild = stuff.SelectSingleNode("//stuffChild"); // ... etc }
问题在于,针对" stuffChild"的XPath查询总是返回第一个" stuff"元素的子元素,而不返回其余元素的子元素。 XPath不能用于查询单个XMLElement吗?
解决方案
回答
XPath表达式开头的" //"从文档根目录开始。尝试" .//stuffChild"。 。是self :: node()的简写,它将设置搜索的上下文,//是后代轴的简写。
所以你有了:
XmlNode stuffChild = stuff.SelectSingleNode(".//stuffChild");
转换为:
xmlNode stuffChild = stuff.SelectSingleNode(" self :: node()/ descendant :: stuffChild");
xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant-or-self::stuffChild");
如果子节点的名称与父节点的名称相同,则需要使用以下稍微冗长的语法,以确保不重新选择父节点:
xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant::stuffChild");
另请注意,如果" stuffChild"是" stuff"的直接后代,则可以完全省略前缀,而只需选择" stuffChild"即可。
XmlNode stuffChild = stuff.SelectSingleNode("stuffChild");
W3Schools教程以易于理解的格式提供了有用的信息。
回答
我们在stuffChild
前面使用的//
表示我们正在从根开始寻找stuffChild
元素。
如果要从当前节点(当前节点的后代)开始,则应使用.//
,如下所示:
stuff.SelectSingleNode(".//stuffChild");
回答
如果" stuffChild"是" stuff"的子节点,则xpath应该只是:
XmlNode stuffChild = stuff.SelectSingleNode("stuffChild");
回答
选择单个节点意味着只需要第一个元素。因此,最好的解决方案是:
XmlNode stuffChild = stuff.SelectSingleNode("descendant::stuffChild[1]");