【问题标题】:Using nokogiri to parse XML and create records with multiple attributes使用 nokogiri 解析 XML 并创建具有多个属性的记录
【发布时间】:2012-07-15 04:57:43
【问题描述】:

感觉我在这里遗漏了一些很明显的东西,但看不到。

我有一个 XML 文件并且正在使用 Nokogiri gem。

XML 看起来像这样(想象一下,如果您将拥有无限数量的“变体”):

<?xml version="1.0" encoding="UTF-8"?> 
<products> 
    <variant> 
        <sku type="string">123abc</sku>
        <inventory-quantity type="integer">68</inventory-quantity> 
    </variant> 
    <variant> 
        <sku type="string">321cba</sku>
        <inventory-quantity type="integer">22</inventory-quantity> 
    </variant>
</products>

我想遍历变体并为每个包含“sku”和“inventory-quantity”属性的记录创建一个相应的记录。

这是我到目前为止所得到的,但不是创建单独的记录,而是在上述情况下创建两条记录并将 Nokogiri 返回的完整数组或 NodeSet 插入到每个记录属性中。所以这个:

doc = Nokogiri::XML(File.open("#{Rails.root}/public/new.xml")) 

variant = doc.xpath("//variant")

variant.each do |product| 

  sku = product.xpath("//sku").text
  quan = product.xpath("//inventory-quantity").text

  Productmapping.create(:sku => sku, :product_quantity => quan)

end

创建这个...

sku              inventory-quantity

123abc321cba     6822
123abc321cba     6822

我真正想要的地方:

sku              inventory-quantity

123ab            68
321cba           22

看起来这是因为 xpath 定位器将所有匹配项返回到一个数组中,我正在调用该数组并将其插入到每条记录中。

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby xml activerecord nokogiri


    【解决方案1】:

    答案很简单——而不是:

    sku = product.xpath("//sku").text
    quan = product.xpath("//inventory-quantity").text
    

    只需使用:

    sku = product.xpath("sku").text
    quan = product.xpath("inventory-quantity").text
    

    这是因为//sku 选择了文档根目录的所有sku 后代。

    【讨论】:

    • 确实很简单,正是我所希望的(并且错过了)。谢谢!
    • 太棒了。谢谢你。耶稣,永远坚持下去!
    【解决方案2】:

    像这样的:

    doc = Nokogiri::XML(File.open("#{Rails.root}/public/new.xml"))  
    
    variant = doc.xpath("//variant")
    
    sku, quan = nil, nil
    variant.each do |product| 
    
    
      product.children.each do |child|
          case child.name
           when 'sku'  
              sku = child.text
           when 'inventory-quantity'
              quan = child.text
           end
        end
    
      Productmapping.create(:sku => sku, :product_quantity => quan)
    
    end
    

    或者更神奇而不美观但紧凑的方式:

    sku = product.children[1].text
    quan = product.children[3].text
    

    【讨论】:

    • 遍历所有的孩子,检查名字是低效的。正如你提到的,按位置索引是“不漂亮的”。最好直接指定,例如product.at('sku').text
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多