我有很多大型 (32 Mb) XML 文件,其中包含来自不同商店的产品信息。我正在使用托管在 Heroku 上的 Rails。
我想解析这些 XML 提要并将这些产品写入我的数据库。我有一个半工作的解决方案,但它非常慢并且太占用内存。
到目前为止,我或多或少都在使用这个:
open_uri_fetched = open(xml_from_url)
xml_list = Nokogiri::HTML(open_uri_fetched)
xml_list.xpath("//product").each do |product|
// parsed nodes
// Model.create()
end
这在一定程度上起到了作用。但是,这导致 Heroku 出现内存问题,导致脚本崩溃。它也很慢(我为 200 多个提要执行此操作)。
Heroku 告诉我通过使用 Nokogiri::XML::Reader 来解决问题,这就是我现在想要做的。
我也研究过使用:
ActiveRecord::Base.transaction do
Model.create()
end
加快 Model.create() 过程。
1. 我的第一个问题:这是解决我的问题的正确方法(或至少是体面的方法)吗?
现在,这就是我尝试做的:
reader = Nokogiri::XML::Reader(File.open('this_feed.xml'))
reader.each do |node|
if node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
if node.name.downcase == xname
puts "Name: " + node.inner_xml
use_name = node.inner_xml
end
end
end
问题 2:但是我在哪里放置模型创建代码?
ActiveRecord::Base.transaction do
Model.create(:name => use_name)
end
如果我把它放在循环中,它会尝试为每个节点创建,这是错误的。我希望在 xml 列表中的每个产品之后调用它,对吗?
如果我创建一个在读取 XML 期间正在构建的哈希(然后用于创建模型创建),那会不会像首先打开 XML 文件那样占用大量内存?
简而言之,XML 文件看起来像这样:
<?xml version="1.0" encoding="UTF-8" ?>
<products>
<product>
<name>This cool product</name>
<categories>
<category>Food</category>
<category>Drinks</category>
</categories>
<SKU />
<EAN />
<description>A long description...</description>
<model />
<brand />
<gender />
<price>126.00</price>
<regularPrice>126.00</regularPrice>
<shippingPrice />
<currency>SEK</currency>
<productUrl>http://www.domain.com/1.html</productUrl>
<graphicUrl>http://www.domain.com/1.jpg</graphicUrl>
<inStock />
<inStockQty />
<deliveryTime />
</product>
</products>