使用XPath(Nokgiri)在NodeSet中查找字符串

时间:2012-07-20 14:46:04

标签: ruby xml xpath nokogiri

我有这个XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE pdf2xml SYSTEM "pdf2xml.dtd">

<pdf2xml>
    <page number="1">
        <text top="91">Rapport</text>
        <text top="102">foo</text>
    </page>
    <page number="2">
        <text top="91">Rapport</text>
        <text top="102">bar</text>
    </page>
    <page number="3">
        <text top="91">Rapport</text>
        <text top="102">asdf</text>
    </page>
</pdf2xml>

我正在这样做:

require 'nokogiri'
doc = Nokogiri::XML(File.read("file.xml"))
pages = doc.xpath("//page")
nodeset = pages[0].xpath("./text") + pages[1].xpath("./text")

我想在nodeset中按字符串找到一个节点,就像这个

一样
irb(main):011:0> nodeset.at_xpath("//text[text()[contains(., 'bar')]]")
=> #<Nokogiri::XML::Element:0x3fea6a4821d4 name="text" attributes=[#<Nokogiri::XML::Attr:0x3fea6a482170 name="top" value="102">] children=[#<Nokogiri::XML::Text:0x3fea6a481cac "bar">]>

但我不想使用//

我设法做到了这一点

irb(main):018:0> nodeset.at_xpath("text()[contains(., 'bar')]")
=> #<Nokogiri::XML::Text:0x3fea6a481cac "bar">

但我想要整个<text>节点。

我的节点集上的xpath查询应该是什么样的?

3 个答案:

答案 0 :(得分:0)

要选择当前节点的父节点,您可以使用..例如,

/pdf2xml/page[1]

指向第一个<page>节点。如果要再次选择其父级,可以编写

/pdf2xml/page[1]/..

这将选择<pdf2xml>的父节点<page>

在类似的行上,您可以使用..在示例中选择parent节点。

有关详细信息,请参阅this

希望这有帮助。

答案 1 :(得分:0)

比选择text()节点然后选择父节点更简单的方法就是首先选择所需的节点:

pages = doc.xpath("//page")
puts pages.xpath("text[contains(.,'bar')]")
#=> <text top="102">bar</text>

如果它让你感觉更好,你可以选择明确地测试text()元素的text子节点,而不是使用元素的等效文本:

pages.xpath("text[contains(text(),'bar')]")

答案 2 :(得分:0)

我刚发现

nodeset.at_xpath("../text[text()[contains(., 'bar')]]")

也有效。

编辑:但我认为这比/..慢。