当我找到匹配的孩子时,我想从XML源返回一个“父”节点。
如果我搜索'ddd':
@doc.xpath('//item[contains(., "ddd")]')
我想返回'第2节'
我找不到关于Nokogiri'where'类型代码的文档。 这甚至可能吗?
<entry>
<match>
<field>Section 1</field>
<child>
<item>aaa</item>
<item>bbb</item>
<item>ccc</item>
</child>
</match>
<match>
<field>Section 2</field>
<child>
<item>ddd</item>
<item>eee</item>
<item>fff</item>
</child>
</match>
<match>
<field>Section 3</field>
<child>
<item>hhh</item>
<item>iii</item>
<item>jjj</item>
</child>
</match>
</entry>
这是一种更准确的XML格式。 我需要在节点树上上下移动以获得第2节。 这可能吗?
<entry>
<match>
<field>
<foo>Section 1</foo>
</field>
<child>
<item>aaa</item>
<item>bbb</item>
<item>ccc</item>
</child>
</match>
<match>
<field>
<foo>Section 2</foo>
</field>
<child>
<item>ddd</item>
<item>eee</item>
<item>fff</item>
</child>
</match>
<match>
<field>
<foo>Section 3</foo>
</field>
<child>
<item>hhh</item>
<item>iii</item>
<item>jjj</item>
</child>
</match>
</entry>
答案 0 :(得分:1)
有一种名为#previous_element
的方法:
# #xpath gives all the matched nodes as a collection.
@doc.xpath('//child[./item[contains(., "ddd")]]').map do |child|
child.previous_element.text
end
# #at_xpath gives first matched node
@doc.at_xpath('//child[./item[contains(., "ddd")]]').previous_element.text
# => Section 2
根据您提供的XML, Section 2
不是父,它是<child>
节点的 sibling 节点。
尝试并测试:
require 'nokogiri'
@doc = Nokogiri::XML.parse <<-XML
<entry>
<match>
<field>Section 1</field>
<child>
<item>aaa</item>
<item>bbb</item>
<item>ccc</item>
</child>
</match>
<match>
<field>Section 2</field>
<child>
<item>ddd</item>
<item>eee</item>
<item>fff</item>
</child>
</match>
<match>
<field>Section 3</field>
<child>
<item>hhh</item>
<item>iii</item>
<item>jjj</item>
</child>
</match>
</entry>
XML
@doc.at_xpath('//child[./item[contains(., "ddd")]]').previous_element.text # => "Section 2"
答案 1 :(得分:1)
您可以在XPath中执行此操作:
@doc.xpath("/entry/match[child/item[contains(., 'ddd')]]/field/foo")
这是使用你的第二个样本。它首先找到match
包含child/item
包含item
后代的ddd
个元素,然后查找foo
元素的match
个元素。
答案 2 :(得分:0)
您可以使用“..”语法(类似于目录文件夹)轻松遍历树。
所以这应该有效:
@doc.xpath('//item[contains(., "ddd")]/..')
or
@doc.xpath('//item[contains(., "ddd")]/../field')