given the following xml document:
<table>
<tr><td>A</td> <td>B</td> <td>C</td></tr>
<tr><td>1</td> <td>2</td> <td>3</td></tr>
<tr><td>a</td> <td>b</td> <td>c</td></tr>
</table>
I am trying to write xpath query to get the diagonal line of the table.
I thought about the following query: //td[count(parent::td/preceding-sibling::tr) 1]
But it's not working (it returns "No Match!" as result).
In the example above, the query need to return <td>A</td> <td>2</td> <td>c</td>
What is the problem with this query ?
CodePudding user response:
You are close. Just change
//td[count(parent::td/preceding-sibling::tr) 1]
to
//td[count(parent::tr/preceding-sibling::tr) 1]
or
//td[count(../preceding-sibling::tr) 1]
and your XPath will select
<td>A</td><td>2</td><td>c</td>
as desired.
See also
Update to answer follow-up question:
Can you explain me please how to read the
preceding-sibling::tr
in the following expression://td[count(parent::tr/preceding-sibling::tr) 1]
?
preceding-sibling::tr
selects all tr
sibling elements before the context element. By counting those for the parent of a given td
element, the whole XPath is able to select the diagonal td
elements because the count of the preceding parent tr
elements effectively gives the row number, and //td[
row number ]
yields only those td
elements where the column number (the nth child td
) equals the row number.
CodePudding user response:
First, I'm not sure why you're getting "No Match!"
no match for the query in your question: the result should be <td>A</td> <td>1</td> <td>a</td>
since the query resolves to 1
(because of the 1
at the end); there is no //td[parent::td]
so the count is 0.
Since you are using xpath 3.0, you can try:
for $k in (1 to count(//tr)) return (//tr[$k]/td[$k])
It works on the table in the question.