我在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"]
这个找不到 price
节点下 products
或 product
因为它没有在选择器中指定,在CSS中的意思是 "先找到资源节点,再找到价格节点,再找到价格节点"。任何不在这个路径中的东西都会被忽略。
大多数时候,我觉得CSS选择器更容易写,更容易理解,视觉上也不那么嘈杂。甚至连Nokogiri文档都推荐使用CSS,就是因为这些原因。