任何人都知道如何使用xpath获取节点的位置?
说我有以下xml:
<a>
<b>zyx</b>
<b>wvu</b>
<b>tsr</b>
<b>qpo</b>
</a>
我可以使用以下xpath查询来选择第三个&lt; b&gt;节点(&lt; b&gt; tsr&lt; / b&gt;):
a/b[.='tsr']
这一切都很好但我想返回该节点的序号位置,例如:
a/b[.='tsr']/position()
(但更多工作!)
甚至可能吗?
编辑:忘记提及我使用.net 2所以它是xpath 1.0!
更新:使用James Sulak的excellent answer结束。对于那些感兴趣的人来说,这是我在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);
}
答案 0 :(得分:90)
尝试:
count(a/b[.='tsr']/preceding-sibling::*)+1.
答案 1 :(得分:9)
您可以使用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>
答案 2 :(得分:7)
我意识到这个帖子很古老......但是......
用节点代替星号会给你带来更好的效果
count(a/b[.='tsr']/preceding::a)+1.
而不是
count(a/b[.='tsr']/preceding::*)+1.
答案 3 :(得分:3)
与先前描述的'previous-sibling'不同,它实际上是要使用的轴,而不是“先行”,它完全不同,它选择文档中当前节点的开始标记之前的所有内容。 (见http://www.w3schools.com/xpath/xpath_axes.asp)
答案 4 :(得分:3)
答案 5 :(得分:1)
简要回答James Sulak的答案。
如果您想要考虑该节点可能不存在并且想要将其保持为纯XPATH,那么尝试以下将在节点不存在时返回0。
count(a/b[.='tsr']/preceding-sibling::*)+number(boolean(a/b[.='tsr']))
答案 6 :(得分:0)
问题是如果没有上下文,节点的位置并不重要。
以下代码将为您提供节点在其父子节点中的位置
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;
}
}
}
}
}
答案 7 :(得分:0)
我做了很多Novell Identity Manager的事情,在这种情况下XPATH看起来有点不同。
假设您要查找的值是一个名为TARGET的字符串变量,那么XPATH将是:
count(attr/value[.='$TARGET']/preceding-sibling::*)+1
另外有人指出,为了节省一些空间字符,以下内容也可以使用:
count(attr/value[.='$TARGET']/preceding::*) + 1
我还在Novell的Cool Solutions上发布了一个更漂亮的版本:Using XPATH to get the position node