有人知道如何使用 XPath 获取节点的位置吗?
假设我有以下 xml:
<a>
<b>zyx</b>
<b>wvu</b>
<b>tsr</b>
<b>qpo</b>
</a>
我可以使用以下 xpath 查询来选择第三个 节点 (tsr):
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);
}
尝试:
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>
我意识到这篇文章很古老……但是……
用节点名替换星号会给你更好的结果
count(a/b[.='tsr']/preceding::a)+1.
代替
count(a/b[.='tsr']/preceding::*)+1.
如果您曾经升级到 XPath 2.0,请注意它提供了函数 index-of,它通过以下方式解决问题:
index-of(//b, //b[.='tsr'])
在哪里:
第一个参数是搜索顺序
第二是搜索什么
与前面所说的不同,“preceding-sibling”实际上是要使用的轴,而不是完全不同的“preceding”,它选择文档中当前节点开始标记之前的所有内容。 (见http://www.w3schools.com/xpath/xpath_axes.asp)
只是对 James Sulak 所做答案的注释。
如果您想考虑节点可能不存在并希望将其保留为纯 XPATH,请尝试以下操作,如果节点不存在,则返回 0。
count(a/b[.='tsr']/preceding-sibling::*)+number(boolean(a/b[.='tsr']))
问题是节点的位置在没有上下文的情况下意义不大。
以下代码将为您提供节点在其父子节点中的位置
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;
}
}
}
}
}
我做了很多 Novell Identity Manager 的工作,而 XPATH 在这种情况下看起来有点不同。
假设您要查找的值在一个名为 TARGET 的字符串变量中,那么 XPATH 将是:
count(attr/value[.='$TARGET']/preceding-sibling::*)+1
另外有人指出,为了节省几个字符的空间,以下内容也可以使用:
count(attr/value[.='$TARGET']/preceding::*) + 1
我还在 Novell 的酷解决方案上发布了一个更漂亮的版本:Using XPATH to get the position node
count
返回 0,但 +1 意味着这将始终等于 1。因此,无论您使用什么字符串,无论它是否匹配,都将始终返回 1 - 这个答案解决了这个问题问题stackoverflow.com/a/27173072/1798234