获取 parent 节点,其中 child = x
Get parent node where child = x
当我找到匹配的 child.
时,我想 return 来自 XML 源的 'parent' 节点
如果我搜索 'ddd':
@doc.xpath('//item[contains(., "ddd")]')
我要return'Section 2'
我找不到关于 'where' Nokogiri 类型代码的文档。
这可能吗??
<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>
有一个名为 #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
不是 parent,它是 sibling <child>
节点的节点。
久经考验:
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"
您可以在 XPath 中执行此操作:
@doc.xpath("/entry/match[child/item[contains(., 'ddd')]]/field/foo")
这是使用您的第二个示例。它首先找到具有 child/item
个后代的 match
元素,其中 item
包含 ddd
,然后找到该 match
的 foo
元素孙子.
您可以使用“..”语法轻松遍历树(类似于目录文件夹)。
所以这应该有效:
@doc.xpath('//item[contains(., "ddd")]/..')
or
@doc.xpath('//item[contains(., "ddd")]/../field')
当我找到匹配的 child.
时,我想 return 来自 XML 源的 'parent' 节点如果我搜索 'ddd':
@doc.xpath('//item[contains(., "ddd")]')
我要return'Section 2'
我找不到关于 'where' Nokogiri 类型代码的文档。 这可能吗??
<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>
有一个名为 #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
不是 parent,它是 sibling <child>
节点的节点。
久经考验:
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"
您可以在 XPath 中执行此操作:
@doc.xpath("/entry/match[child/item[contains(., 'ddd')]]/field/foo")
这是使用您的第二个示例。它首先找到具有 child/item
个后代的 match
元素,其中 item
包含 ddd
,然后找到该 match
的 foo
元素孙子.
您可以使用“..”语法轻松遍历树(类似于目录文件夹)。
所以这应该有效:
@doc.xpath('//item[contains(., "ddd")]/..')
or
@doc.xpath('//item[contains(., "ddd")]/../field')