使用Nokogiri解析具有多个值的节点的XML

时间:2015-09-16 20:29:27

标签: ruby-on-rails ruby xml nokogiri

我不太清楚XML语法是什么,这就是为什么我会提出两种类型的XML,请指出好的。

我的XML具有多个值的节点:

案例1:

<items>
  <item>
    <image_urls>http://static.elefant.ro/images/26/95226/husa-belkin-grip-pentru-kindle-3-ebook-reader-albastru_1_categorie.jpg http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg
    </image_urls>
  </item>
</items>

案例2:

<items>
  <item>
    <image_urls>
http://static.elefant.ro/images/26/95226/husa-belkin-grip-pentru-kindle-3-ebook-reader-albastru_1_categorie.jpg
    </image_urls>
    <image_urls>http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg
    </image_urls>
  </item>
</items>

我面临的斗争是通过Nokogiri获得多值节点。我试过了:

item.at("image_urls").to_s.split(" ").inject([]) { |result, element| 
  result << element 
}

但这仅适用于XML的第一个变体。如果正确的语法是第二种形式,我相信它是如何,我怎么能取两个值,因为我的下面的实现只采用第一种形式?

xml = Nokogiri::XML(File.open(self.file.current_path))
xml.xpath("//item").each do |item|
attachments_array = item.at("image_urls").inject([]) { |result, element| 
  result << element
}

1 个答案:

答案 0 :(得分:2)

您需要使用返回所有匹配项的css方法,而不是仅返回第一个匹配项的at

text = <<EOD
<items>
  <item>
    <image_urls>http://static.elefant.ro/images/26/95226/husa-belkin-grip-pentru-kindle-3-ebook-reader-albastru_1_categorie.jpg http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg
    </image_urls>
  </item>
  <item>
    <image_urls>
http://static.elefant.ro/images/26/95226/husa-belkin-grip-pentru-kindle-3-ebook-reader-albastru_1_categorie.jpg</image_urls>
<image_urls>http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg
    </image_urls>
  </item>
</items>
EOD

xml = Nokogiri::XML(text)

xml.css('item').each do |item|
  attachments = item.css('image_urls').map do |url| 
    url.text.strip!.split(' ')
  end.flatten
  p attachments
end
# ["http://static.elefant.ro/images/26/95226/husa-belkin-grip-pentru-kindle-3-ebook-reader-albastru_1_categorie.jpg", "http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg"]
# ["http://static.elefant.ro/images/26/95226/husa-belkin-grip-pentru-kindle-3-ebook-reader-albastru_1_categorie.jpg", "http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg"]