如何使用Ruby创建,读取和转换XML文件

时间:2016-10-30 18:34:48

标签: ruby xml xslt

我正在从Musicbrainz.org下载XML记录,应用XSLT转换并输出新的不同XML记录。

我遇到了一个问题,我想知道它是否是我的方法,XSLT转换或将Ruby应用于文本的限制。

我下载了记录:

require 'open-uri'
mb_metadata = open('http://musicbrainz.org/ws/2/release/?query=barcode:744861082927', 'User-Agent' => 'MarcBrainz marc4brainz@gmail.com').read
File.open('mb_record.xml', 'w').write(mb_metadata)

这很好用。

然后我想转换那条记录。首先我尝试使用Nokogiri:

# mb_metadata to transformed record
mb_record = Nokogiri::XML(File.read('mb_record.xml'))

#if we have the xslt document locally this introduces it
template = Nokogiri::XSLT(File.read('mb_to_marc.xsl'))

# this transforms the input document with the template.xslt
puts template.transform(mb_record)

如果我自己运行它可以工作,但是如果我下载记录然后运行它没有,它会生成一个转换记录,其中只包含一些插入,原始XML文件中没有元素被转换

所以我认为这可能是Nokogiri的一个问题,然后我尝试使用Ruby / XSLT gem:

xslt = XML::XSLT.new()
xslt.xml = 'mb_record.xml'
xslt.xsl = 'mb_to_marc.xsl'

out = xslt.serve()
print out;

同样,如果我在本地文件上运行它,它可以工作,但是如果我下载它并尝试转换它它不起作用 - 它会产生以下错误:

xslt.xml = 'mb_record.xml'

如果我只是在已经下载的文件上运行它们,两种方法都可以正常工作。

那么问题是什么?它是命名问题,XSLT问题还是别的什么?

这是整个剧本:

#!/usr/bin/env ruby
# encoding: UTF-8
require 'rubygems' if RUBY_VERSION >= '1.9'
require 'pathname'
require 'httpclient'
require 'xml/xslt'
require 'nokogiri'
require 'open-uri'


# DOWNLOAD RECORD FROM MusicBrainz.org - this works
mb_metadata = open('http://musicbrainz.org/ws/2/release/?query=barcode:744861082927', 'User-Agent' => 'MarcBrainz marc4brainz@gmail.com').read
#puts record
File.open('mb_record.xml', 'w').write(mb_metadata)



# mb_metadata to transformed record - this works on a saved file but not if the file is created earlier in this file .
#

#mb_record = Nokogiri::XML(File.read('mb_record.xml'))

#if we have the xslt document locally this introduces it
#template = Nokogiri::XSLT(File.read('mb_to_marc.xsl'))

# this is supposed to transform the input document with the template.xslt
#puts template.transform(mb_record)

# TRYING ANOTHER TACK
# This works if acting on a saved file. i.e. if I comment out the nokogiri lines above and just run the lines below - to 'print out' the xml is correctly transfored by the xslt to produce more xml.
# I added 'sleep 3' to see if that would help but it doesn't make a difference.
xslt = XML::XSLT.new()
xslt.xml = 'mb_record.xml'
xslt.xsl = 'mb_to_marc.xsl'

out = xslt.serve()
print out;

1 个答案:

答案 0 :(得分:1)

File.open('mb_record.xml', 'w').write(mb_metadata)

最好写成

File.write('mb_record.xml', mb_metadata)

第一个将导致文件未被关闭,并且可能没有刷新到磁盘,这可能意味着文件没有内容,或者只有部分内容。

第二个写入文件并立即刷新并关闭它。