无法使用Nokogiri从XML文档中检索Google命名空间中的数据

时间:2017-06-12 20:20:59

标签: ruby xml namespaces nokogiri google-shopping

我有这个Google购物Feed:

<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
  <item>
    <title>test</title>
    <g:id>1</g:id>
    <g:color>blue</g:color>
  </item>
  <item>
    <title>test2</title>
    <g:id>2</g:id>
    <g:color>red</g:color>
  </item>
</channel></rss>

我现在已经找了好几天了,我似乎无法找到答案。我还通过Nokogiri文档进行了工作,但这也没有解决任何问题。

我想做什么:

doc = Nokogiri::XML(*Google Shopping Feed*)
doc.css('channel > item').each do |item|
  puts item.css('g:id')
end

但这没有任何回报。我尝试了很多建议,但似乎没有任何建议。显然我错过了这里的一些东西,但我无法弄清楚是什么。

我无法弄清楚的另一件事是检索项目中所有属性的列表。所以我的问题是如何从Google购物Feed中检索以下数组:

# attributes => ['title', 'g:id', 'g:color']

2 个答案:

答案 0 :(得分:0)

如果要保留命名空间信息,最简单的解决方案可能是使用Xpath表达式。

的内容
doc.xpath('//item').each_with_index do |node, i|
  puts "Element #{i} attributes:"
  node.xpath("*/text()").each do |element| 
    puts "#{element.name}: #{element.text}"
  end
end

答案 1 :(得分:0)

尝试使用at_xpathtext

doc.css('channel > item').each do |item|
  puts item.at_xpath('g:id').text
end
#=> 1
#=> 2
  

我无法弄清楚的另一件事是检索所有的列表   项目中的属性。

您可以像这样获得每个item的数组:

doc.css('channel > item').map do |item|
  item.element_children.map do |key|
    prefix = "#{key.namespace.prefix}:" if key.namespace
    name   = key.name

    "#{prefix}#{name}"
  end
end
#=> [["title", "g:id", "g:color"], ["title", "g:id", "g:color"]]

如果所有项目都具有完全相同的属性,那么您可以使用第一个元素(而不是迭代所有项目):

doc.css('channel > item').first.element_children.map do |key|
  prefix = "#{key.namespace.prefix}:" if key.namespace
  name   = key.name

  "#{prefix}#{name}"
end
#=> ["title", "g:id", "g:color"]