Я пытаюсь разобрать эту XML-структуру с помощью XPath от Nokogiri.

<root>
  <resource id='1' name='name1>
     <prices>
         <price datefrom='2015-01-01' dateto='2015-05-31' price='3000' currency='EUR'></price>
         <price datefrom='2015-06-01' dateto='2015-12-31' price='4000' currency='EUR' ></price>                        
     </prices>
  </resource>
  <!-- many more resource nodes -->
<root>

Я повторяю каждый ресурс, и для каждого ресурса мне нужно получить его элементы <prices>:

resourcesParsed = Nokogiri::XML(resourcesXML)
    resources = resourcesParsed.xpath("//resource")      
      for resource in resources do
        id = resource["id"]
        # insert in resources tables
        # parsing resource prices
        getPrices(resource)
      end
    ...

def getPrices(resource)
  prices = resource.xpath("//price") 
  @logger.debug "prices=" + prices.to_s
  # do whatever
end 

По какой-то причине, когда я пытаюсь разобрать //price, он получает не только узлы <price> внутри ресурса, но и все узлы <prices> во всем XML-документе.

Как я могу анализировать только узлы <price> ресурса?

0
Rober 27 Окт 2015 в 12:11

2 ответа

Лучший ответ

Я понял.

Вместо того:

prices = resource.xpath("//price") 

Я должен поискать:

prices = resource.xpath(".//price") 

Чтобы указать на текущий узел.

2
Rober 27 Окт 2015 в 09:49

Я бы написал такой код:

resources = doc.search('resource').map{ |resource|
  [
    resource['id'],
    resource.search('price').map{ |price|
      {
        price:    price['price'],
        datefrom: price['datefrom'],
        dateto:   price['dateto'],
        currency: price['currency']
      }
    }
  ]
}

На этом этапе resources представляет собой массив массивов хешей, каждый подмассив представляет собой resource со своими встроенными ценами:

# => [["1",
#      [{:price=>"3000",
#        :datefrom=>"2015-01-01",
#        :dateto=>"2015-05-31",
#        :currency=>"EUR"},
#       {:price=>"4000",
#        :datefrom=>"2015-06-01",
#        :dateto=>"2015-12-31",
#        :currency=>"EUR"}]]]

Было бы немного проще повторно использовать это для поиска или дальнейшей обработки, если это хэш подмассивов, где каждый подмассив представляет собой price:

resources.to_h
# => {"1"=>
#      [{:price=>"3000",
#        :datefrom=>"2015-01-01",
#        :dateto=>"2015-05-31",
#        :currency=>"EUR"},
#       {:price=>"4000",
#        :datefrom=>"2015-06-01",
#        :dateto=>"2015-12-31",
#        :currency=>"EUR"}]}
1
the Tin Man 30 Окт 2015 в 23:43