Feels like I’m missing something pretty obvious here but can’t see it.
I have an XML file and are using the Nokogiri gem.
The XML looks like this (imagine if you will an infinite amount of ‘variants’):
<?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>
I want to loop over the variants and create a corresponding record for each that contains the ‘sku’ and ‘inventory-quantity’ attributes.
This is what I’ve got so far, but instead of creating individual records, in the above case it creates two records and inserts the complete array or NodeSet that Nokogiri returns into each records attribute. So this:
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
creates this…
sku inventory-quantity
123abc321cba 6822
123abc321cba 6822
Where I actually want:
sku inventory-quantity
123ab 68
321cba 22
It looks like it’s because the xpath locator returns all occurrences into an array and I’m calling that array and inserting it for each record.
Thanks!
The answer is simple – instead of:
just use:
It’s because
//skuselects all the sku descendants of the document root.