繁体   English   中英

Rails 4将XML解析为表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM