使用xpath查找节点的位置
任何人都知道如何获得使用xpath节点的位置?
说我有以下的XML:
<a> <b>zyx</b> <b>wvu</b> <b>tsr</b> <b>qpo</b> </a>
我可以使用下面的xpath查询来select第三个<b>节点(<b> tsr </ b>):
a/b[.='tsr']
哪一个都好,但我想返回该节点的序号位置,如下所示:
a/b[.='tsr']/position()
(但多一点工作!)
这甚至有可能吗?
编辑 :忘了提及我使用.net 2,所以它的xpath 1.0!
更新 :结束了使用詹姆斯苏拉克的优秀答案 。 对于那些感兴趣的是我在C#中的实现:
int position = doc.SelectNodes("a/b[.='tsr']/preceding-sibling::b").Count + 1; // Check the node actually exists if (position > 1 || doc.SelectSingleNode("a/b[.='tsr']") != null) { Console.WriteLine("Found at position = {0}", position); }
尝试:
count(a/b[.='tsr']/preceding-sibling::*)+1.
你可以用XSLT来做到这一点,但我不确定直XPath。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="a/*[text()='tsr']"> <xsl:number value-of="position()"/> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet>
我意识到,这个职位是古老的..但..
用nodenamereplace星号会给你更好的结果
count(a/b[.='tsr']/preceding::a)+1.
代替
count(a/b[.='tsr']/preceding::*)+1.
不同于前面说过的“先兄弟”实际上是使用的轴,而不是完全不同的“之前”,它select文档中当前节点的开始标签之前的所有内容。 (见http://www.w3schools.com/xpath/xpath_axes.asp )
问题在于,没有上下文,节点的位置并不意味着太多。
下面的代码将给你在其父节点的父节点的位置
using System; using System.Xml; public class XpathFinder { public static void Main(string[] args) { XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(args[0]); foreach ( XmlNode xn in xmldoc.SelectNodes(args[1]) ) { for (int i = 0; i < xn.ParentNode.ChildNodes.Count; i++) { if ( xn.ParentNode.ChildNodes[i].Equals( xn ) ) { Console.Out.WriteLine( i ); break; } } } } }
请注意James Sulak所做的答案。
如果要考虑节点可能不存在并且希望保持纯粹的XPATH,则尝试以下操作,如果该节点不存在,则返回0。
count(a/b[.='tsr']/preceding-sibling::*)+number(boolean(a/b[.='tsr']))
如果你升级到XPath 2.0,注意它提供了函数索引 ,它解决了这个问题:
index-of(//b, //b[.='tsr'])
哪里:
- 第一个参数是search的顺序
- 第二是什么search
我做了很多Novell Identity Manager的工作,XPATH在这方面看起来有些不同。
假设你正在查找的值是一个名为TARGET的stringvariables,那么XPATH将是:
count(attr/value[.='$TARGET']/preceding-sibling::*)+1
此外,有人指出,为了节省一些空间的字符,下面的工作也是如此:
count(attr/value[.='$TARGET']/preceding::*) + 1
我还在Novell的Cool Solutions上发布了一个更漂亮的版本: 使用XPATH获取位置节点