使用Ruby/Nokogiri将XML节点解析为CSV

gor*_*laz 2 ruby xml csv nokogiri

Ruby在这里解析新手.

我有一个看起来像的XML文件;

?xml version="1.0" encoding="iso-8859-1"?>
<Offers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ssc.channeladvisor.com/files/cageneric.xsd">
  <Offer>
   <Model><![CDATA[11016001]]></Model>
   <Manufacturer><![CDATA[Crocs, Inc.]]></Manufacturer>
   <ManufacturerModel><![CDATA[11016-001]]></ManufacturerModel>
   ...lots more nodes
   <Custom6><![CDATA[<li>Bold midsole stripe for a sporty look.</li>
    <li>Odor-resistant, easy to clean, and quick to dry.</li>
    <li>Ventilation ports for enhanced breathability.</li>
    <li>Lightweight, non-marking soles.</li>
    <li>Water-friendly and buoyant; weighs only ounces.</li>
    <li>Fully molded Croslite&trade; material for lightweight cushioning and comfort.</li>
    <li>Heel strap swings back for snug fit, forward for wear as a clog.</li>]]></Custom6>
  </Offer>
....lots lots more <Offer> entries
</Offers>
Run Code Online (Sandbox Code Playgroud)

我想要做的是将每个'Offer'实例解析为CSV中我自己的行,我正在通过此代码执行:

require 'csv'
require 'nokogiri'

file = File.read('input.xml')
doc = Nokogiri::XML(file)
a = []
csv = CSV.open('output.csv', 'wb') 

doc.css('Offer').each do |node|
    a.push << node.content.split
end

a.each { |a| csv << a } 
Run Code Online (Sandbox Code Playgroud)

哪个运行得很好(一旦我认为CSV需要一个数组馈送到它,将.split放到node.content上'a'似乎满足).

我的问题是我在分割空格而不是提供节点的每个元素(对不起,如果这不是正确的术语?)所以每个单词都进入csv中自己的列.

有没有人得到一些指示;

  1. 一种获取每个节点内容的方法
  2. 如何通过csv中的标题拉出节点名称

任何指针都非常赞赏

谢谢,利亚姆

Jac*_*own 6

这假设每个Offer元素始终具有相同的子节点(尽管它们可以为空):

CSV.open('output.csv', 'wb') do |csv|
  doc.search('Offer').each do |x|
    csv << x.search('*').map(&:text)
  end
end
Run Code Online (Sandbox Code Playgroud)

并获取标题(来自第一个Offer元素):

CSV.open('output.csv', 'wb') do |csv|
  csv << doc.at('Offer').search('*').map(&:name)
  doc.search('Offer').each do |x|
    csv << x.search('*').map(&:text)
  end
end
Run Code Online (Sandbox Code Playgroud)

编辑

search并且at是可以采取XPath或CSS选择器串引入nokogiri功能.at将返回第一次出现的元素; search将提供匹配元素的数组(如果未找到匹配项,则为空数组).在*这种情况下会选择属于当前节点的直接子的所有节点.

二者nametext也引入nokogiri函数(的元素).name提供元素的名称; text提供节点的文本或CDATA内容.