【问题标题】:Find string in NodeSet with XPath (Nokgiri)使用 XPath 在 NodeSet 中查找字符串 (Nokgiri)
【发布时间】:2012-07-22 07:14:01
【问题描述】:

我有这个 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">

但我想要整个 &lt;text&gt; 节点。

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

【问题讨论】:

  • 我一写完问题就震惊了:我可以通过nodeset.at_xpath("text()[contains(., 'bar')]").parent 获得&lt;text&gt; 节点。仍然很好奇如何在 xpath 中找到它。

标签: ruby xml xpath nokogiri


【解决方案1】:

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

/pdf2xml/page[1]

指向第一个&lt;page&gt; 节点。如果你想再次选择它的父母,你可以写

/pdf2xml/page[1]/..

这将选择&lt;pdf2xml&gt; 节点,它是&lt;page&gt; 的父节点。

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

更多信息可以参考this

希望这会有所帮助。

【讨论】:

  • 你说得对,nodeset.at_xpath("text()[contains(., 'bar')]/..") 是我想要的。谢谢!
【解决方案2】:

比选择text()节点然后选择父节点更简单的是,首先选择你想要的节点:

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

如果它让您感觉更好,您也可以显式测试text 元素的text() 子节点,而不是使用该元素的等效文本:

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

【讨论】:

  • 就我而言,我不想对pages 进行查询,我想对nodeset 进行查询(其中包含来自&lt;text&gt;&lt;text&gt; 节点的子集@ )。也许我应该在我的问题中更加明确,但我相信其他人可能会从这个解决方案中受益。谢谢。
【解决方案3】:

我才发现

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

也可以。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    相关资源
    最近更新 更多