使用HTML :: TreeBuilder :: XPath模块访问父节点或兄弟节点的Xpath表达式

时间:2011-10-13 23:16:25

标签: xml perl xpath

我想使用HTML :: TreeBuilder :: XPath Perl模块选择节点的父节点或兄弟节点,让我们按如下方式获取示例HTML:

<tbody>
    <tr>
        <td class="c1">Match_Text</td>
        <td class="c2">Extact_Text</td>
    </tr>
    <tr>
        <td class="c1"></td>
        <td class="c2"></td>
    </tr>
</tbody>

所以我想为此提取文本“Match_Text”,我将xpath表达式表示为:

'/html/body//td[@class="c1"]="Match_Text"/../td[@class="c2"]'

这是我的用例的有效表达式。

但看起来父母没有实现,我从perl模块得到以下错误:

  

轴axis_parent未实现[无法定位对象方法   “getParentNode”通过包“XML :: XPathEngine :: Literal”在   /usr/local/share/perl/5.10.1/XML/XPathEngine/Step.pm第326行。]

任何人都可以建议一个可能适用于我的用例的替代Xpath表达式(访问节点的父/兄弟)。请注意,我只想使用Xpath表达式,并且不想创建DOM并显式遍历树。

3 个答案:

答案 0 :(得分:3)

错误消息具有误导性。问题不是缺乏支持,而是你试图找到比较返回的布尔值的父级。它没有。

您可以使用

//*[ td[@class="c1" and text()="Match_Text"] ]/td[@class="c2"]

//td[@class="c1" and text()="Match_Text"]/following-sibling::*

//td[@class="c1" and text()="Match_Text"]/following-sibling::td[@class="c2"]

//td[@class="c1" and text()="Match_Text"]/../td[@class="c2"]

答案 1 :(得分:0)

我以前没见过任何类似的工作表达方式。实际上,我认为错误是由于该表达式没有很好地编写和解析。

无论如何,这里有两个替代目标 - 尽管未使用指定的Perl模块进行测试:

//td[@class="c1" and text()="Match_Text"]/../td[@class="c2"]
//td[@class="c2" and ../td[@class="c1" and text()="Match_Text"]]

shell-toolsonline-toolz上进行了测试。

答案 2 :(得分:0)

  

我想使用选择节点的父节点或兄弟节点   HTML :: TreeBuilder :: XPath Perl模块。

在任何情况下,当您想要一个选择多个节点的XPath表达式并且您知道这些节点的每个节点都有一个单独的XPath表达式时,您可以简单地使用标准的XPath联合运算符|,如下所示:

 (/*/body//*[td[@class="c1"and . = 'Match_Text']])[1]
|
  (/*/body//*[td[@class="c1"and . = 'Match_Text']])[1]
               /td[[@class="c1"and not(. = 'Match_Text')]

在此XPath表达式中,|运算符的第一个操作数是引用节点的父元素,union运算符的第二个参数是一个表达式,用于选择此父级的所有子元素,其字符串值为与参考节点不同。

结果是选择了两个节点集的并集。