如何使用Nokogiri和XPath获取特定的XML节点?

问题描述 投票:0回答:1

我在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

然而,我同时得到了资源元素下的价格和产品下的价格。我对产品下的价格不感兴趣。

xpath nokogiri
1个回答
1
投票

2个选项与XPath :

.//price[parent::prices[parent::resource]]
.//price[ancestor::*[2][name()="resource"]]

输出:3个节点

如果要添加一个日期条件,你可以使用你所做的。

.//price[parent::prices[parent::resource]][translate(@dateto, '-', '') >= 20200101]

1
投票

我会这样做。

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 节点下 productsproduct 因为它没有在选择器中指定,在CSS中的意思是 "先找到资源节点,再找到价格节点,再找到价格节点"。任何不在这个路径中的东西都会被忽略。

大多数时候,我觉得CSS选择器更容易写,更容易理解,视觉上也不那么嘈杂。甚至连Nokogiri文档都推荐使用CSS,就是因为这些原因。

© www.soinside.com 2019 - 2024. All rights reserved.