XML解析元素和元素属性到数组中

时间:2014-12-08 15:20:44

标签: ruby arrays xml nokogiri

我正在尝试将一些XML解析为数组。这是我正在解析的XML的一大块:

<Group_add>
  <Group org_pac_id="0000000001">
    <org_legal_name>NAME OF GROUP</org_legal_name>
    <par_status>Y</par_status>
    <Quality>
      <GPRO_status>N</GPRO_status>
      <ERX_status>N</ERX_status>
    </Quality>
    <Profile_Spec_list>
      <Spec>08</Spec>
    </Profile_Spec_list>
    <Location adrs_id="OR974772594SP2280XRDXX300">
      <other_tags>xx</other_tags>
    </Location>
  </Group>
  <Group org_pac_id="0000000002">
    ...
  </Group>

</Group_add>

我目前能够获得&#34; Group&#34;的属性。以及&#34; org_legal_name&#34;并使用下面的代码将它们添加到数组中。

def parse(input_file, output_array)
    puts "Parsing #{input_file} data. Please wait..."
    doc = Nokogiri::XML(File.read(input_file))
    doc.xpath("//Group").each do |group|
        ["org_legal_name"].each do |name|
            output_array << [group["org_pac_id"], group.at(name).inner_html]
        end
    end
end

我想添加位置&#34; adrs_id&#34;也可以输出到output_array,但似乎无法计算出那部分。

示例输出:

["0000000001", "NAME OF GROUP", "OR974772594SP2280XRDXX300"]
["0000000002", "NAME OF GROUP 2", "OR974772594SP2280XRDXX301"]

1 个答案:

答案 0 :(得分:2)

从:

开始
require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<xml>
  <Group org_pac_id="0000000001">
          <org_legal_name>NAME OF GROUP</org_legal_name>
          <Location adrs_id="OR974772594SP2280XRDXX300">
              <other_tags>xx</other_tags>
          </Location>
  </Group>
</xml>
EOT

根据您的XML,我会使用:

array = []
array << doc.at('org_legal_name').text
array << doc.at('Location')['adrs_id']
array # => ["NAME OF GROUP", "OR974772594SP2280XRDXX300"]

如果XML更复杂,我怀疑它是,那么我们需要一个准确的,最小的例子。


基于更新的XML(仍然可疑),这是我使用的内容。请注意,我删除了与问题没有密切关系的信息,以便将XML减少到所需的最小值:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<xml>
  <Group_add>
    <Group org_pac_id="0000000001">
      <org_legal_name>NAME OF GROUP</org_legal_name>
      <Location adrs_id="OR974772594SP2280XRDXX300">
        <other_tags>xx</other_tags>
      </Location>
    </Group>
    <Group org_pac_id="0000000002">
      <org_legal_name>NAME OF ANOTHER GROUP</org_legal_name>
      <Location adrs_id="OR974772594SP2280XRDXX301">
        <other_tags>xx</other_tags>
      </Location>
    </Group>
  </Group_add>
</xml>
EOT

data = doc.search('Group').map do |group|
  [
    group['org_pac_id'],
    group.at('org_legal_name').text,
    group.at('Location')['adrs_id']
  ]
end

结果是:

data # => [["0000000001", "NAME OF GROUP", "OR974772594SP2280XRDXX300"], ["0000000002", "NAME OF ANOTHER GROUP", "OR974772594SP2280XRDXX301"]]

group变量视为占位符传递给块。从该节点可以轻松地向下查看DOM,并抓取仅适用于该特定节点的内容。

请注意,我使用的是CSS而不是XPath选择器。它们更容易阅读,通常工作正常。有时我们需要XPath的附加功能,有时Nokogiri使用jQuery的CSS访问器为我们提供了有用的东西。

相关问题