Find position of a node using xpath

2019-01-02 20:36发布

Anyone know how to get the position of a node using xpath?

Say I have the following xml:

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

I can use the following xpath query to select the third <b> node (<b>tsr</b>):

a/b[.='tsr']

Which is all well and good but I want to return the ordinal position of that node, something like:

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

(but a bit more working!)

Is it even possible?

edit: Forgot to mention am using .net 2 so it's xpath 1.0!


Update: Ended up using James Sulak's excellent answer. For those that are interested here's my implementation in 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);
}

标签: xpath
8条回答
有味是清欢
2楼-- · 2019-01-02 20:57

Unlike stated previously 'preceding-sibling' is really the axis to use, not 'preceding' which does something completely different, it selects everything in the document that is before the start tag of the current node. (see http://www.w3schools.com/xpath/xpath_axes.asp)

查看更多
余生请多指教
3楼-- · 2019-01-02 21:00

Try:

count(a/b[.='tsr']/preceding-sibling::*)+1.
查看更多
余欢
4楼-- · 2019-01-02 21:03

If you ever upgrade to XPath 2.0, note that it provides function index-of, it solves problem this way:

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

Where:

  • 1st parameter is sequence for searching
  • 2nd is what to search
查看更多
其实,你不懂
5楼-- · 2019-01-02 21:06

You can do this with XSLT but I'm not sure about straight 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>
查看更多
长期被迫恋爱
6楼-- · 2019-01-02 21:09

I do a lot of Novell Identity Manager stuff, and XPATH in that context looks a little different.

Assume the value you are looking for is in a string variable, called TARGET, then the XPATH would be:

count(attr/value[.='$TARGET']/preceding-sibling::*)+1

Additionally it was pointed out that to save a few characters of space, the following would work as well:

count(attr/value[.='$TARGET']/preceding::*) + 1

I also posted a prettier version of this at Novell's Cool Solutions: Using XPATH to get the position node

查看更多
怪性笑人.
7楼-- · 2019-01-02 21:11

I realize that the post is ancient.. but..

replace'ing the asterisk with the nodename would give you better results

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

instead of

count(a/b[.='tsr']/preceding::*)+1.
查看更多
登录 后发表回答