假设我有一个包含以下行的HTML表,
...
<tr>
<th title="Library of Quintessential Memes">LQM:</th>
<td>
<a href="docs/lqm.html"><b>Intro</b></a>
<a href="P/P79/">79</a>
<a href="P/P80/">80</a>
<a href="P/P81/">81</a>
<a href="P/P82/">82</a>
</td>
</tr>
<tr>
<th title="Library of Boring Books">LBB:</th>
<td>
<a href="docs/lbb.html"><b>Intro</b></a>
<a href="R/R80/">80</a>
<a href="R/R81/">81</a>
<a href="R/R82/">82</a>
<a href="R/R83/">83</a>
<a href="R/R84/">84</a>
</td>
</tr>
...
我想选择<a>
元素中的所有<td>
元素,其关联的<th>
文本位于一小组固定标题中(例如LQM,LBR和RTT) 。如何将其表示为XPath查询?
<tr>
子项与正则表达式匹配的所有<th>
元素,则选择其余<a>
个元素的所有<tr>
个后代,这将是出色的。
答案 0 :(得分:2)
以下XPath将起作用:
//a[contains(',LQM:,LBR:,RTT:,',
concat(',', ancestor::td/preceding-sibling::th, ','))]
理论上,这可能会产生一些误报(如果您的代码包含逗号)。
更严格的说法是:
//a[ancestor::td/preceding-sibling::th[.='LQM:']]
|//a[ancestor::td/preceding-sibling::th[.='LBR:']]
|//a[ancestor::td/preceding-sibling::th[.='RTT:']]
我通过在输入周围添加<table>
标记并应用以下XSL转换来测试此内容:
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="//a[ancestor::td/preceding-sibling::th[.='LQM:']]
|//a[ancestor::td/preceding-sibling::th[.='LBR:']]
|//a[ancestor::td/preceding-sibling::th[.='RTT:']]">
<xsl:text>
</xsl:text>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:transform>
它产生以下输出:
<a href="docs/lqm.html"><b>Intro</b></a>
<a href="P/P79/">79</a>
<a href="P/P80/">80</a>
<a href="P/P81/">81</a>
<a href="P/P82/">82</a>
当然,如果您使用的是XSL,那么您可能会发现这种结构更具可读性:
<xsl:for-each select="//a">
<xsl:variable name="header" select="ancestor::td/preceding-sibling::th"/>
<xsl:if test="$header='LQM:' or $header = 'LBR:' or $header = 'RTT:'">
<xsl:text>
</xsl:text>
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>