将 XML 转换为 Ruby 哈希时保留属性

Cod*_*ker 3 ruby hash ruby-on-rails xml-parsing

我有一个大型 XML 文档需要解析。在本文档中,许多标签具有不同的属性。例如:

<album>
 <song-name type="published">Do Re Mi</song-name>
</album>
Run Code Online (Sandbox Code Playgroud)

目前,我通过 require 来使用 Rail 的哈希解析库'active_support/core_ext/hash'

当我将其转换为哈希值时,它会删除属性。它返回:

{"album"=>{"song-name"=>"Do Re Mi"}}
Run Code Online (Sandbox Code Playgroud)

如何维护这些属性(在本例中为type="published"属性)?

这似乎是之前在“ How can I use XML attribute when conversion into a hash with from_xml? ”中被问到的,它没有结论性的答案,但那是从 2010 年开始的,我很好奇从那时起情况是否发生了变化。或者,我想知道您是否知道解析此 XML 的替代方法,以便我仍然可以包含属性信息。

the*_*Man 5

将 XML 转换为散列并不是一个好的解决方案。您留下的散列比原始 XML 更难解析。另外,如果 XML 太大,您将留下一个无法放入内存且无法处理的散列,而原始 XML 可以使用 SAX 解析器进行解析。

假设该文件在加载时不会占用您的内存,我建议使用Nokogiri来解析它,执行以下操作:

require 'nokogiri'

class Album

  attr_reader :song_name, :song_type
  def initialize(song_name, song_type)
    @song_name = song_name
    @song_type = song_type
  end
end

xml = <<EOT
<xml>
  <album>
   <song-name type="published">Do Re Mi</song-name>
  </album>
  <album>
    <song-name type="unpublished">Blah blah blah</song-name>
  </album>
</xml>
EOT

albums = []
doc = Nokogiri::XML(xml)
doc.search('album').each do |album|
  song_name = album.at('song-name')
  albums << Album.new(
      song_name.text,
      song_name['type']
    )
end

puts albums.first.song_name
puts albums.last.song_type
Run Code Online (Sandbox Code Playgroud)

哪个输出:

Do Re Mi
unpublished
Run Code Online (Sandbox Code Playgroud)

该代码首先定义一个合适的对象,用于保存所需的数据。当 XML 被解析为 DOM 时,代码将循环遍历所有<album>节点,并提取信息,定义类的实例,并将其附加到数组中albums

运行后,您将拥有一个数组,您可以遍历并处理每个项目,将其存储到数据库中,或者按照您想要的方式操作它。不过,如果您的目标是将该信息插入数据库,那么您最好让 DBM 读取 XML 并直接导入它。