XPath position predicates

T

Tom Anderson

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
 
M

Martin Honnen

Tom said:
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]
 
T

Tom Anderson

Tom said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top