Как получить указанный c XML узел с Nokogiri и XPath - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть эта структура в 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 ]

1 голос
/ 29 апреля 2020

Я бы сделал это следующим образом:

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 -ese означает «найти узел ресурса, затем узел цен, затем узлы цен». Все, что не находится на этом пути, игнорируется.

Большую часть времени я считаю, что селекторы CSS легче писать, понимать и они менее визуально шумят. Даже в документах Nokogiri по этим причинам рекомендуется использовать CSS.

1 голос
/ 28 апреля 2020

2 варианта с XPath:

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

Вывод: 3 узла

И чтобы добавить условие даты, вы можете использовать то, что вы сделали:

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