使用Ruby将XML转换为JSON并将其保存为单独的文件

pprl5pva  于 2023-03-24  发布在  Ruby
关注(0)|答案(3)|浏览(132)

我是Ruby程序员新手,刚刚接到一个新任务,转换大量的XML并将其保存到单独的JSON文件中。例如:

<listing>
  <id>abc12345</id>
  <name>BCD</name>
  <address>12 Main St</address>
</listing>

<listing>
  <id>a1b2c3d4</id>
  <name>XYZ</name>
  <address>14 Main St</address>
</listing>

<listing>
  <id>bcde45678</id>
  <name>MNO</name>
  <address>14 Broadway</address>
</listing>

我想将其保存到单独的文件中,并使用id作为本例的文件名,分别为abc12345.json、a1b2c3d4.json和bcde45678.json,每个文件都包含如下内容:

{
  "listing": {
    "id": "bcde45678",
    "name": "MNO",
    "address": "14 Broadway"
  }
}

任何人都可以帮助我解决这个问题。对于所有未来的帮助,我真的很感激

j1dl9f46

j1dl9f461#

我假设你想将清单块以JSON格式打印到单独的文件中。如果你可以访问'active_support/core_ext'和'nokogiri',并且你不太关心XML如何转换为JSON,你可以这样做:

require 'active_support/core_ext'
require 'nokogiri'

xml = Nokogiri::XML(File.read "yourfile")

xml.search("//listing").each do |l|
  filename = l.at_xpath("id").content
  File.open(filename + '.json', 'w') do |file|
    file.print Hash.from_xml(l.to_xml).to_json
  end
end
hjqgdpho

hjqgdpho2#

这是一个使用XMLSimple(或者不使用,这是你的毒药选择)和使用JSON的核心模块扩展的好例子:

require 'json/add/core'
require 'xmlsimple'

xml_files = [
'<listing>
  <id>abc12345</id>
  <name>BCD</name>
  <address>12 Main St</address>
</listing>',
'<listing>
  <id>a1b2c3d4</id>
  <name>XYZ</name>
  <address>14 Main St</address>
</listing>',
'<listing>
  <id>bcde45678</id>
  <name>MNO</name>
  <address>14 Broadway</address>
</listing>'
]

xml_files.each do |xml|
  obj = XmlSimple.xml_in(xml, :ForceArray => false)
  File.write(obj['id'] + '.json', JSON.pretty_generate(obj))
end

这将创建三个文件:
a1b2c3d4.json:

{
  "id": "a1b2c3d4",
  "name": "XYZ",
  "address": "14 Main St"
}

abc12345.json:

{
  "id": "abc12345",
  "name": "BCD",
  "address": "12 Main St"
}

bcde45678.json:

{
  "id": "bcde45678",
  "name": "MNO",
  "address": "14 Broadway"
}

我怀疑XMLSimple是基于Perl的XMLSimple,它读取XML文件并将其转换为本机对象。在本例中,它将创建XML的散列,允许轻松访问<id>标记的内容作为普通散列键。XMLSimple具有并且需要很大的灵活性来将传入的XML解析为对象,因此我使用:ForceArray => false标志对其进行了微调。这使得代码在创建散列键的值时有一定的灵活性。你需要花一些时间仔细阅读文档来了解它的选项。
JSON.pretty_generate(obj)创建格式良好的输出。这会增加文件大小,但如果您需要人工读取这些文件,则可以使用obj.to_json生成更紧凑的输出,这将减少阅读JSON文件时的I/O时间。
它负责编写XML的各个块。
你没有说“巨大”是什么意思。在我的世界里,巨大可以是几个GB的文件,甚至是两位数。对于一个非常大的XML文件,我建议使用Nokogiri::SAX来使用流处理并生成小的XML文件,类似于你的示例XML。然后你可以使用上面的代码迭代这些文件。
如果文件不是很大,只是很大,让Nokogiri将整个文件解析成DOM,遍历<listing>节点,并将它们输出到文件。您给出的示例XML对于真正的XML文件无效,因为它缺少包含节点,因此,基于“固定”版本:

require 'json/add/core'
require 'nokogiri'
require 'xmlsimple'

xml_files =<<EOT
<xml_root>
  <listing>
    <id>abc12345</id>
    <name>BCD</name>
    <address>12 Main St</address>
  </listing>
  <listing>
    <id>a1b2c3d4</id>
    <name>XYZ</name>
    <address>14 Main St</address>
  </listing>
  <listing>
    <id>bcde45678</id>
    <name>MNO</name>
    <address>14 Broadway</address>
  </listing>
</xml_root>
EOT

doc = Nokogiri::XML(xml_files)

xml_files = []
doc.search('listing').each do |listing|
  xml_file = listing.at('id').text + '.xml'
  xml_files << xml_file
  File.write(xml_file, listing.to_xml)
end

xml_files.each do |file|
  obj = XmlSimple.xml_in(File.read(file), :ForceArray => false)
  File.write(obj['id'] + '.json', JSON.pretty_generate(obj))
end

运行后,这些文件存在,JSON文件的内容与对应的XML文件关联:

a1b2c3d4.json  a1b2c3d4.xml   abc12345.json  abc12345.xml   bcde45678.json bcde45678.xml

对于简单的XML,你可以不用XMLSimple,但是对于大型XML块,下面的方法可能有点麻烦,但是,至少你可以选择。下面是不使用SimpleXML的方法:

require 'json/add/core'
require 'nokogiri'

xml_files =<<EOT
<xml_root>
  <listing>
    <id>abc12345</id>
    <name>BCD</name>
    <address>12 Main St</address>
  </listing>
  <listing>
    <id>a1b2c3d4</id>
    <name>XYZ</name>
    <address>14 Main St</address>
  </listing>
  <listing>
    <id>bcde45678</id>
    <name>MNO</name>
    <address>14 Broadway</address>
  </listing>
</xml_root>
EOT

doc = Nokogiri::XML(xml_files)

xml_files = []
doc.search('listing').each do |listing|
  id, name, address = %w[id name address].map { |node| listing.at(node).content }
  File.write(
    id + '.json',
    {
      'id'      => id,
      'name'    => name,
      'address' => address
    }.to_json
  )
end
z2acfund

z2acfund3#

尝试将XML转换为JSON并保存单独的新JSON文件

require "rubygems"
require "crack"
require "json"

folder_path = '/xml_files/local/folder_path'

Dir.foreach(folder_path) do |xml_file|

  next if xml_file == '.' || xml_file == '..'
  myXML = Crack::XML.parse(File.read("/local/folder_path/#{xml_file}"))
  myJSON = JSON.pretty_generate(myXML)

  filename_without = xml_file.sub(".xml", "")
  
  File.open("created_json_files_local_path/#{filename_without}.json", 'w') do |f|
   f.write(myJSON)
  end

end

相关问题