XPath / HTML: select a node based on the corresponding node

<html> <body> <table> <tr> <th>HeaderA</th> <th>HeaderB</th> <th>HeaderC</th> <th>HeaderD</th> </tr> <tr> <td>ContentA</td> <td>ContentB</td> <td>ContentC</td> <td>ContentD</td> </tr> </table> </body> </html> 

I am looking for the most efficient way to select the contents of a "td" node based on the header in the corresponding "th" node ..

My current expression is xPath ..

 /html/body/table/tr/td[count(/html/body/table/tr/th[text() = 'HeaderA']/preceding-sibling::*)+1] 

Some questions..

  • Can you use relative paths ( ../.. ) inside count() ?
  • What other options exist for finding the current node number td[?] Or count(/preceding-sibling::*)+1 most effective?
+7
html xpath
source share
4 answers
  • You can use relative paths inside count()
  • I have never heard of another way to find the node number ...

Here is the code with relative xpath code inside count ()

 /html/body/table/tr/td[count(../../tr/th[text()='HeaderC']/preceding-sibling::*)+1] 

But well, it is not much shorter ... It will not be shorter than this, in my opinion:

 //td[count(../..//th[text()='HeaderC']/preceding-sibling::*)+1] 
+3
source share

Harmen's answer is exactly what you need for a clean XPATH solution.

If you are really interested in performance , then you can define the XSLT key :

 <xsl:key name="columns" match="/html/body/table/tr/th" use="text()"/> 

and then use the key in the predicate filter:

 /html/body/table/tr/td[count(key('columns', 'HeaderC')/preceding-sibling::th)+1] 

However, I suspect that you probably won’t be able to see a measurable difference in performance unless you need to filter a lot by column (for example, for each ) with checks for each row for a really large document).

+2
source share

I would leave Xpath aside ... since I assume that the DOM is parsed, I would use the map data structure and manually map the nodes both on the client side and the server side (JavaScript / Java).

It seems to me that XPath is beyond its limits.

+1
source share

Maybe you need axis position () and XPath?

0
source share

All Articles