<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>
Я ищу самый эффективный способ выбрать содержание 'td' узел на основе заголовка в соответствующем 'th' узле..
Мое текущее выражение XPath..
/html/body/table/tr/td[count(/html/body/table/tr/th[text() = 'HeaderA']/preceding-sibling::*)+1]
Некоторые вопросы..
../..
) внутри count()
?td[?]
или count(/preceding-sibling::*)+1
самое эффективное?count()
Вот код с относительным xpath-кодом внутри count()
/html/body/table/tr/td[count(../../tr/th[text()='HeaderC']/preceding-sibling::*)+1]
Но он не намного короче... На мой взгляд, он не будет короче этого:
//td[count(../..//th[text()='HeaderC']/preceding-sibling::*)+1]
Ответ Хармена - это именно то, что вам нужно для чистого XPATH-решения.
Если вас действительно интересует производительность, то вы можете определить XSLT-ключ:
<xsl:key name="columns" match="/html/body/table/tr/th" use="text()"/>
, а затем используйте ключ в вашем предикатном фильтре:
/html/body/table/tr/td[count(key('columns', 'HeaderC')/preceding-sibling::th)+1]
Однако, я подозреваю, что вы, вероятно, не сможете увидеть измеримую разницу в производительности, если только вам не потребуется многократно фильтровать столбцы (например, для каждого цикла с проверкой каждой строки для действительно большого документа).
.Я бы оставил Xpath в стороне... так как я предполагаю, что это был анализ DOM, я бы использовал структуру данных Map, и вручную сравнил бы узлы либо на стороне клиента, либо на стороне сервера (JavaScript / Java).
Похоже, что XPath здесь наклонен за его пределы.
.