[英]Rails 4 parse XML to table
我有XML文件,例如http://www.heureka.cz/direct/xml-export/shops/heureka-sekce.xml 。 我无法更改它,因为它不是我的。 它只是从另一个网站进行解析。
这是XML(具有结构):
<HEUREKA>
<CATEGORY>
<CATEGORY_ID>971</CATEGORY_ID>
<CATEGORY_NAME>Auto-moto</CATEGORY_NAME>
<CATEGORY>
<CATEGORY_ID>881</CATEGORY_ID>
<CATEGORY_NAME>Alkohol testery</CATEGORY_NAME>
<CATEGORY_FULLNAME>Heureka.cz | Auto-moto | Alkohol testery</CATEGORY_FULLNAME>
</CATEGORY>
</CATEGORY>
</HEUREKA>
感谢所有评论,这里是最终代码
def heureka
require 'open-uri'
require 'nokogiri'
doc = Nokogiri::XML(open("http://www.heureka.cz/direct/xml-export/shops/heureka-sekce.xml"))
doc.xpath("//CATEGORY[CATEGORY_FULLNAME]").each do |node|
record = Heureka.where("name" => node.css('CATEGORY_NAME').inner_text).first_or_initialize
record.fullname=node.xpath('CATEGORY_FULLNAME').inner_text
record.name=node.xpath('CATEGORY_NAME').inner_text
record.save unless record.fullname.blank?
end
end
在这个地方使用nokogiri似乎有点小。 您可以使用纯红宝石来做到这一点:
require 'net/http'
xml_content = Net::HTTP.get(URI.parse('http://www.heureka.cz/direct/xml-export/shops/heureka-sekce.xml'))
data = Hash.from_xml(xml_content)
然后您就可以将数据作为哈希对象进行访问。
如果我们缩进您的XML,您将看到问题:
<HEUREKA>
<CATEGORY>
<CATEGORY_ID>971</CATEGORY_ID>
<CATEGORY_NAME>Auto-moto</CATEGORY_NAME>
<CATEGORY>
<CATEGORY_ID>881</CATEGORY_ID>
<CATEGORY_NAME>Alkohol testery</CATEGORY_NAME>
<CATEGORY_FULLNAME>Heureka.cz | Auto-moto | Alkohol testery</CATEGORY_FULLNAME>
</CATEGORY>
</CATEGORY>
</HEUREKA>
第二个类别节点位于第一个类别节点内,因此它也是其子节点。 因此, children.css('CATEGORY_NAME').inner_text
将为第一个节点返回两个串联的名称( Auto-motoAlkohol testery
),最后一个将具有预期的数据-( Alkohol testery
)。
修正您的XML:
<HEUREKA>
<CATEGORY>
<CATEGORY_ID>971</CATEGORY_ID>
<CATEGORY_NAME>Auto-moto</CATEGORY_NAME>
</CATEGORY>
<CATEGORY>
<CATEGORY_ID>881</CATEGORY_ID>
<CATEGORY_NAME>Alkohol testery</CATEGORY_NAME>
<CATEGORY_FULLNAME>Heureka.cz | Auto-moto | Alkohol testery</CATEGORY_FULLNAME>
</CATEGORY>
</HEUREKA>
然后再试一次...
更新资料
如果无法更改XML,则可以使用XPATH
代替CSS
,因为它的默认行为是查找直接子级,而不是所有子级(深子级):
def heurekacat
require 'open-uri'
require 'nokogiri'
doc = Nokogiri::XML(open("http://www.heureka.cz/direct/xml-export/shops/heureka-sekce.xml"))
doc.css("CATEGORY").each do |node|
record = HeurekaCat.where("name" => children.xpath('CATEGORY_NAME').inner_text).first_or_initialize
record.category=node.xpath('CATEGORY_FULLNAME').inner_text
record.name=node.xpath('CATEGORY_NAME').inner_text
record.save
end
end
只需更改一行:
doc.css("CATEGORY").each do |node|
到以下内容:
doc.css("CATEGORY:has(CATEGORY_FULLNAME)").each do |node|
这仅选择CATEGORY
含有元素CATEGORY_FULLNAME
子元素。
或者,等效的XPath:
doc.xpath("//CATEGORY[CATEGORY_FULLNAME]").each do |node|
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.