如何使用 Nokogiri 和 XPath 获取特定的 XML 节点
How to get a specific XML node with Nokogiri and XPath
我在XML中有这个结构:
<resource id="2023984310000103605" name="Rebelezza">
<prices>
<price datefrom="2019-10-31" dateto="2019-12-31" price="2690.0" currency="EUR" />
<price datefrom="2020-01-01" dateto="2020-03-31" price="2690.0" currency="EUR" />
<price datefrom="2020-03-31" dateto="2020-04-30" price="3200.0" currency="EUR" />
</prices>
<products>
<product name="specific-product1">
<prices>
<price datefrom="2019-10-31" dateto="2019-12-31" price="2690.0" currency="EUR" />
<price datefrom="2020-01-01" dateto="2020-03-31" price="2690.0" currency="EUR" />
<price datefrom="2020-03-31" dateto="2020-04-30" price="3200.0" currency="EUR" />
</prices>
</product>
</products>
</resource>
如何使用 XPath 选择器只获取资源下的价格而不获取产品内部的价格。
此刻,我有这样的东西:
resources = resourcesParsed.xpath("//resource")
for resource in resources do
prices = resource.xpath(".//prices/price[number(translate(@dateto, '-', '')) >= 20190101]")
end
但是,我同时获得资源元素和产品下的价格。我对产品下的价格不感兴趣。
2 个 XPath 选项:
.//price[parent::prices[parent::resource]]
.//price[ancestor::*[2][name()="resource"]]
输出:3 个节点
要添加日期条件,您可以使用您所做的:
.//price[parent::prices[parent::resource]][translate(@dateto, '-', '') >= 20200101]
我会这样做:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<resource>
<prices>
<price price="1"/>
</prices>
<products>
<product>
<prices>
<price price="-1"/>
</prices>
</product>
</products>
</resource>
EOT
doc.search('resource > prices > price').map { |p| p['price'] }
# => ["1"]
这不会在 products
或 product
下找到 price
节点,因为它没有在选择器中指定,在 CSS-ese 中意味着 "find the resource node then the prices node then the price nodes"。不在该路径中的任何内容都将被忽略。
大多数时候我发现 CSS 选择器更容易编写、理解,并且视觉上的干扰更少。由于这些原因,即使是 Nokogiri 文档也建议使用 CSS。
我在XML中有这个结构:
<resource id="2023984310000103605" name="Rebelezza">
<prices>
<price datefrom="2019-10-31" dateto="2019-12-31" price="2690.0" currency="EUR" />
<price datefrom="2020-01-01" dateto="2020-03-31" price="2690.0" currency="EUR" />
<price datefrom="2020-03-31" dateto="2020-04-30" price="3200.0" currency="EUR" />
</prices>
<products>
<product name="specific-product1">
<prices>
<price datefrom="2019-10-31" dateto="2019-12-31" price="2690.0" currency="EUR" />
<price datefrom="2020-01-01" dateto="2020-03-31" price="2690.0" currency="EUR" />
<price datefrom="2020-03-31" dateto="2020-04-30" price="3200.0" currency="EUR" />
</prices>
</product>
</products>
</resource>
如何使用 XPath 选择器只获取资源下的价格而不获取产品内部的价格。
此刻,我有这样的东西:
resources = resourcesParsed.xpath("//resource")
for resource in resources do
prices = resource.xpath(".//prices/price[number(translate(@dateto, '-', '')) >= 20190101]")
end
但是,我同时获得资源元素和产品下的价格。我对产品下的价格不感兴趣。
2 个 XPath 选项:
.//price[parent::prices[parent::resource]]
.//price[ancestor::*[2][name()="resource"]]
输出:3 个节点
要添加日期条件,您可以使用您所做的:
.//price[parent::prices[parent::resource]][translate(@dateto, '-', '') >= 20200101]
我会这样做:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<resource>
<prices>
<price price="1"/>
</prices>
<products>
<product>
<prices>
<price price="-1"/>
</prices>
</product>
</products>
</resource>
EOT
doc.search('resource > prices > price').map { |p| p['price'] }
# => ["1"]
这不会在 products
或 product
下找到 price
节点,因为它没有在选择器中指定,在 CSS-ese 中意味着 "find the resource node then the prices node then the price nodes"。不在该路径中的任何内容都将被忽略。
大多数时候我发现 CSS 选择器更容易编写、理解,并且视觉上的干扰更少。由于这些原因,即使是 Nokogiri 文档也建议使用 CSS。