首页 文章

使用xpath查找节点的位置

提问于
浏览
79

任何人都知道如何使用xpath获取节点的位置?

说我有以下xml:

<a>
    <b>zyx</b>
    <b>wvu</b>
    <b>tsr</b>
    <b>qpo</b>
</a>

我可以使用以下xpath查询来选择第三个<b>节点(<b> tsr </ b>):

a/b[.='tsr']

这一切都很好,但我想 return 该节点的序数位置,如:

a/b[.='tsr']/position()

(但更多工作!)

它甚至可能吗?

edit :忘了提到我正在使用.net 2所以它是xpath 1.0!


Update :结束使用James Sulakexcellent 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);
}

8 回答

  • 8

    与前面所述不同,'preceding-sibling'实际上是要使用的轴,而不是完全不同的'preceding',它选择文档中当前节点的开始标记之前的所有内容 . (见http://www.w3schools.com/xpath/xpath_axes.asp

  • 0

    如果您曾升级到XPath 2.0,请注意它提供了函数index-of,它以这种方式解决了问题:

    index-of(//b, //b[.='tsr'])
    

    哪里:

    • 第一个参数是搜索序列

    • 第二是搜索的内容

  • 6

    请注意James Sulak的答案 .

    如果您想要考虑节点可能不存在并且想要将其保持为纯XPATH,那么尝试以下将在节点不存在时返回0 .

    count(a/b[.='tsr']/preceding-sibling::*)+number(boolean(a/b[.='tsr']))
    
  • 2

    尝试:

    count(a/b[.='tsr']/preceding-sibling::*)+1.
    
  • 3

    您可以使用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>
    
  • 0

    我意识到这个帖子很古老..但..

    用节点代替星号可以给你更好的结果

    count(a/b[.='tsr']/preceding::a)+1.
    

    代替

    count(a/b[.='tsr']/preceding::*)+1.
    
  • 1

    问题是没有上下文,节点的位置并没有多大意义 .

    以下代码将为您提供其父子节点中节点的位置

    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;
                    }
                }
            }
        }
    }
    
  • 85

    我做了很多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

相关问题