XPath position predicates

Discussion in 'XML' started by Tom Anderson, May 6, 2009.

  1. Tom Anderson

    Tom Anderson Guest

    Hello everybody,

    This may be a stupid question, but i've been banging my brain against it
    all afternoon, and as such i'm no longer think good.

    Given this XML:

    <table id="mytable">
    <tr>
    <td class="left">port</td>
    <td class="right">starboard</td>
    </tr>
    <tr>
    <td class="left">gauche</td>
    <td class="right">droite</td>
    </tr>
    <tr>
    <td class="left">sinister</td>
    <td class="right">dexter</td>
    </tr>
    </table>

    (a) Should this XPath expression find the cell containing 'starboard':

    table[@id='mytable']/tr[1]/td[@class='right']

    (b) Should these XPath expressions (i) mean the same thing and (ii) find
    the cell containing 'starboard':

    (1) table[@id='mytable']/tr/td[@class='right'][1]
    (2) table[@id='mytable']//td[@class='right'][1]
    (3) table[@id='mytable']//td[@class='right' and position()=1]

    ?

    I wrote some code on the assumption that the answer to (b)(ii) was 'yes',
    but it didn't work. I'm not sure if this is a mistaken assumption on my
    part, a failure to translate a correct assumption into correct code, or a
    bug in my XPath library (Xalan 2.7.1).

    My thinking had been that if you have an expression E that identifies a
    node set, then E[n] selects the nth node of that set. But fiddling and
    reading, it dawned on me that this isn't the case, but rather that E[n]
    means the members of E which are the nth child of their parents - in this
    case, the tr elements. That would be fine, but what i found rather
    counterintuitive is that example (b)(2), which is the form of expression i
    was using, contains no explicit mention of any tr, and so that means
    you're indexing into completely mysterious parent elements!

    In conclusion, sometimes i love XPath, and sometimes i hate it.

    Thanks,
    tom

    --
    I have come to believe that the whole world is an enigma, a harmless
    enigma that is made terrible by our own mad attempt to interpret it as
    though it had an underlying truth. -- Umberto Eco
    Tom Anderson, May 6, 2009
    #1
    1. Advertising

  2. Tom Anderson wrote:

    > This may be a stupid question, but i've been banging my brain against it
    > all afternoon, and as such i'm no longer think good.
    >
    > Given this XML:
    >
    > <table id="mytable">
    > <tr>
    > <td class="left">port</td>
    > <td class="right">starboard</td>
    > </tr>
    > <tr>
    > <td class="left">gauche</td>
    > <td class="right">droite</td>
    > </tr>
    > <tr>
    > <td class="left">sinister</td>
    > <td class="right">dexter</td>
    > </tr>
    > </table>
    >
    > (a) Should this XPath expression find the cell containing 'starboard':
    >
    > table[@id='mytable']/tr[1]/td[@class='right']


    Yes.

    > (b) Should these XPath expressions (i) mean the same thing and (ii) find
    > the cell containing 'starboard':
    >
    > (1) table[@id='mytable']/tr/td[@class='right'][1]
    > (2) table[@id='mytable']//td[@class='right'][1]
    > (3) table[@id='mytable']//td[@class='right' and position()=1]
    >
    > ?
    >
    > I wrote some code on the assumption that the answer to (b)(ii) was
    > 'yes', but it didn't work. I'm not sure if this is a mistaken assumption
    > on my part, a failure to translate a correct assumption into correct
    > code, or a bug in my XPath library (Xalan 2.7.1).
    >
    > My thinking had been that if you have an expression E that identifies a
    > node set, then E[n] selects the nth node of that set.


    I think you want
    (E)[n]
    so e.g.
    (table[@id='mytable']/tr/td[@class='right'])[1]

    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
    Martin Honnen, May 6, 2009
    #2
    1. Advertising

  3. Tom Anderson

    Tom Anderson Guest

    On Wed, 6 May 2009, Martin Honnen wrote:

    > Tom Anderson wrote:
    >
    >> My thinking had been that if you have an expression E that identifies a
    >> node set, then E[n] selects the nth node of that set.

    >
    > I think you want
    > (E)[n]
    > so e.g.
    > (table[@id='mytable']/tr/td[@class='right'])[1]


    I finally got round to testing this, and of course you're absolutely
    right. Thanks!

    tom

    --
    Our only chance for survival is better engineering. -- James Dyson
    Tom Anderson, May 19, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alfraed
    Replies:
    0
    Views:
    802
    Alfraed
    Jul 14, 2003
  2. Martin Buchleitner
    Replies:
    6
    Views:
    27,758
    Moody
    Jul 17, 2003
  3. Soren Kuula
    Replies:
    2
    Views:
    556
    Malcolm Dew-Jones
    Apr 13, 2005
  4. Maitre Bart
    Replies:
    0
    Views:
    428
    Maitre Bart
    Oct 22, 2004
  5. Altu
    Replies:
    9
    Views:
    556
    Peter Flynn
    Oct 7, 2007
Loading...

Share This Page