在一个课程中,我们的老师给了我们一个项目,将CSV转换为XML格式,再次从XML转换为CSV,并告诉我们在Python和Ruby之间进行选择。我更喜欢Ruby,因为它对我来说似乎更容易理解。
我已完成第一部分,从CSV转换为XML,并且工作正常。但是当我想从XML转换为CSV时,我的代码可以工作,但仅适用于特定的XML文件。我想让它适用于任何XML文件。
这是我的XML,我不会把它全部放在一边因为它很大:
<?xml version="1.0"?>
<records>
<company>
<id>p1</id>
<name>Skoda</name>
<price>10000</price>
<stock>4</stock>
<country>Czech Republic</country>
</company>
<company>
<id>p2</id>
<name>Mercedes</name>
<price>50000</price>
<stock>5</stock>
<country>Germany</country>
</company>
<company>
<id>p3</id>
<name>Alfa Romeo</name>
<price>18000</price>
<stock>19</stock>
<country>Italy</country>
</company>
<company>
<id>p4</id>
<name>Fiat</name>
<price>1500</price>
<stock>15000</stock>
<country>Italy</country>
</company>
</records>
我的用于XML到CSV转换的Ruby代码是:
xmlinputfile = gets.chomp
print "\n"
csvoutputfile = gets.chomp
print "\n"
puts "Writing CSV..."
print "\n"
xml_file = File.open(xmlinputfile, "r")
xml = REXML::Document.new( xml_file )
csv_file = File.new(csvoutputfile, "w")
xml.elements.each("records") do |e|
e.elements.each("company") do |f|
csv_file.puts f.elements['id'].text + "," + f.elements['name'].text + ","
+ f.elements['price'].text + "," +
f.elements['stock'].text + ","+ f.elements['country'].text + ","
end
end
print "Job Done !!! \n"
puts "Contents of #{xmlinputfile} were written in CSV format to #{csvoutputfile}.\n\n"
问题是这个Ruby代码只能用于上面的XML,而不能用于任何其他XML代码,因为我找不到让代码自己读取XML标签的方法,并放置他们的内容为CSV格式。在上面的代码中,我将自己的XML标记作为
中的字符串参数f.elements [ 'XML_TAG']
因此它可以采用其内容并以CSV格式写入。但这并不好,因为当我使用另外一个带有更多标签的XML时,它将不起作用。
我想要做的是,当我插入xml输入文件的名称时,代码可以找到xml中有多少个标签并将其内容放入CSV格式。
请它非常重要。我必须在3天内完成这个项目,我几乎试了一个星期,没有做任何事情。你们是我的最后一次机会!
答案 0 :(得分:0)
require 'nokogiri' # http://nokogiri.org aka gem install nokogiri
xmldoc = Nokogiri::XML(IO.read("records.xml"))
rows = []
xmldoc.xpath('/*/*').each do |row_xml|
row_values = []
rows << row_values
row_xml.xpath('./*').each do |field|
row_values << field.text
end
end
require 'pp'
pp rows
#=> [["p1", "Skoda", "10000", "4", "Czech Republic"],
#=> ["p2", "Mercedes", "50000", "5", "Germany"],
#=> ["p3", "Alfa Romeo", "18000", "19", "Italy"],
#=> ["p4", "Fiat", "1500", "15000", "Italy"]]
或者更简洁地说,您可以通过以下方式获得相同的结果:
rows = xmldoc.xpath('/*/*').map{ |row| row.xpath('./*').map(&:text) }
如果你想要'列'的名字:
columns = xmldoc.xpath('/*/*[position()=1]/*').map(&:name)
#=> ["id", "name", "price", "stock", "country"]