86

My sample input XML is:

<root>
 <a>
   <b>item</b>
   <b>item1</b>
   <b>item2</b>
   <b>item3</b>
   <b>item4</b>
 </a>
</root>

I am suppose to select a node b whose position is the value of a variable.

How can I use the value of a variable to test the position of a node?

iliketocode
  • 6,978
  • 5
  • 46
  • 60
IordanTanev
  • 5,974
  • 4
  • 37
  • 49

2 Answers2

111

you can use this:

/root/a/b[position()=$variable]

position() is 1 based

http://saxon.sourceforge.net/saxon6.5.3/expressions.html

remi bourgarel
  • 8,737
  • 3
  • 37
  • 71
62

The following should work:

/root/a/b[2]

And if it doesn't, try:

/root/a/b[position()=2]
Ronald Wildenberg
  • 31,091
  • 12
  • 88
  • 130
  • 1
    I came here to find the difference between these two, could you please explain how they are different? – Andre Jan 07 '16 at 11:14
  • 12
    `position()` refers to the position in the dom [2] refers to the second result in the list of results. – Becky Conning Jul 01 '16 at 10:19
  • 2
    @Andre. When used inside a `for-each` loop `select` statement, they are the same. When `position()` is used within the loop itself, it refers to the result set. The `[n]` format only works as a shorthand because it is the only conditional inside the `[ ]` block, otherwise `position()` must be used, as in `//a[(@id="xx") and (position()=3)]`, which is "any fifth link that has an `id` of xx". – Patanjali Jan 14 '19 at 06:46
  • @Patanjali That is confusing - links with the position() of 3 are the 5th links? It seems to me [2] could be used instead of :nth-of-type(2), while [position()=2] would be the equivalent of :nth-child(2) then? I guess we need a couple of examples to clear the fog. – bitoolean Aug 11 '19 at 11:04
  • @Patanjali I think I understood the part about it being a shorthand now that I've tested it and it does only give me the "item1" by running `\\*[2]` and `\\*[position()=2]` against the question's XML. Thank you! – bitoolean Aug 11 '19 at 20:55
  • @bitoolean. Sorry, yes it should be 'third'. `[2]` is the shorthand for `[position()=2]`. Note that `//*[2]` or `//*[position())=2]` is the equivalent of `*:nth-child(2)`, but `//*[name()='a'][2]` is the equivalent of `a:nth-of-type[2]`, the latter saying select the second element of name 'a'. That is, each successive `[]` is executed on the result set from the immediately preceding `[]`. – Patanjali Aug 12 '19 at 14:25