使用XPath 1.0导航HTML表列

时间:2010-08-09 17:34:36

标签: xpath html-table

仅使用XPath表达式(而不是在XSLT或DOM中 - 只是纯XPath),我正在尝试创建从当前节点(在td中)到相同列中的相关td的相对路径HTML表格。

例如,假设我有这种类型的数据:

<table>
  <tr> <td><a>Blue Jeans</a></td> <td><a>Shirt</a></td> </tr>
  <tr> <td><span>$21.50</span></td> <td><span>$18.99</span></td> </tr>
</table>

我和“蓝色牛仔裤”在一起,想要找到价格(21.50美元)。在XSLT中,我可以使用current()函数来得到这样的答案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:apply-templates select="//a" />
    </xsl:template>

    <xsl:template match="a"> 
        Name: <xsl:value-of select="."/>
        Price: <xsl:value-of select="../../following-sibling::tr[1]/td[position() = count(current()/../preceding-sibling::td) + 1]" />
    </xsl:template>

</xsl:stylesheet>

但我遇到的问题是XPath 1.0中没有定义current()。我尝试使用self :: axis,但是喜欢“。”简写,只指向“上下文”节点,而不是“当前”节点。我在XPath standard中看到的语言表明XPath没有“当前节点”的概念。

是否有另一种形成此路径的方法或者这是XPath的限制?

2 个答案:

答案 0 :(得分:1)

在XPath 1.0中你可以这样做:

/table/tr/td/a[.='Blue Jeans']/following::td[count(../td)]/span

当然,这假设没有colspan。

编辑:证据。这个样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text"/>
    <xsl:param name="pProduct" select="'Blue Jeans'"/>
    <xsl:template match="/">
        <xsl:value-of select="/table/tr/td/a[.=$pProduct]
                                    /following::td[count(../td)]/span"/>
    </xsl:template>
</xsl:stylesheet>

输出:

$21.50

将参数pProduct设置为'Shirt',输出:

$18.99

注意:当然,您需要在上下文中使用a元素才能选择span元素。所以,使用样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text"/>
    <xsl:template match="text()"/>
    <xsl:template match="a">
        Name: <xsl:value-of select="."/>
        Price: <xsl:value-of select="following::td[count(../td)]/span" />
    </xsl:template>
</xsl:stylesheet>

输出:

Name: Blue Jeans
Price: $21.50
Name: Shirt
Price: $18.99

答案 1 :(得分:0)

使用单个XPath 1.0表达式无法实现

在XPath 2.0中可以写:

for $vPreceeding in count(../preceding-sibling::td)
  return ../../following-sibling::tr[1]/td[$vPreceeding]