XPath/HTML:根据相关节点选择节点

7
<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>

我希望找到一种最有效的方法,基于相应的'th'节点中的标题,选择内容为'td'的节点。

我的当前xPath表达式..

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

一些问题..

  • count()中可以使用相对路径(../..)吗?
  • 寻找当前节点编号的其他选项是什么,td[?]还是count(/preceding-sibling::*)+1最有效?
4个回答

3
  • count()中可以使用相对路径
  • 我从未听说过其他找到节点编号的方法...

这是带有相对xpath代码的计数(count)的代码:

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

但是,这并没有短多少...在我看来,它不会比这更短:

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

很好。我并不是特别在寻找表达式的最短方式,而是最有效的方式,以尽量减少内部查找。 - chameleon95

2
Harmen的回答正是您需要的纯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]

然而,我怀疑除非您需要经常筛选列(例如,在非常大的文档中使用带有每行检查的for-each循环),否则您可能无法看到性能上的可衡量差异。

1

我会把XPath放在一边...因为我假设它是DOM解析的,我会使用Map数据结构,在客户端或服务器端(JavaScript / Java)手动匹配节点。

对我来说,XPath在这里被拉伸到了极限。


我仍然认为XPath不是最好的解决方案,投票反对也无法改变我的想法...或事实... - Eran Medan
我理解并感激您的评论。我正在寻找使用xPath的最有效方法。然后,我可以在我的环境中使用所有可用选项(如xPath、java、javascript等)进行真实世界基准测试,以确定最终解决方案。感谢您的评论。 - chameleon95

0

也许你需要使用position()和XPath轴?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接