使用Nokogiri搜索XML文档以获取特定路径并进行更改

时间:2014-05-22 16:52:54

标签: ruby xml cucumber nokogiri

使用Nokogiri搜索XML文档以获取特定路径并进行更改(使用前面的Cucumber)

我想在XML文档中搜索特定路径,然后将其更改为其他路径。这是XML的相关部分:

<Root>
 <Application>   
  <Connections>
   <AutoAccept>true</AutoAccept>
  <AllowDomains/>
  </Connections>
  <Streams>
   <StreamType>default</StreamType>
    <StorageDir>/C:/blah/flash/</StorageDir>

我想将“/ C:/ blah / flash /”更改为其他值。这就是我的代码方式:

Given(/^Update the Apreso configuration file$/) do 
  xmldoc = Nokogiri::XML(DATA['DATA_WOWZA1'])
  xmldoc.search("/Root/Application/Streams/StorageDir").each do |node|
  node.content = "Newpath"
 end

 puts xmldoc.to_xml
end

“DATA_WOWZA1”是我通过YAML文件传递的XML文件的路径。当我运行它传递的代码但XML文件没有反映出变化时,想法?

2 个答案:

答案 0 :(得分:1)

您需要为Nokogiri::XML提供一串XML,而不是文件路径字符串。尝试:

xmldoc = Nokogiri::XML(File.read DATA['DATA_WOWZA1'])

但是,获得原始XML输出并没有意义。您确定您的测试正在输出XML吗?

如果您想将文件保存到位,则需要执行以下操作:

File.open(DATA['DATA_WOWZA1'], 'w') { |f| f.puts xmldoc.to_xml }

答案 1 :(得分:0)

如果只有一个StorageDir节点,那么您的工作太辛苦了:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<Root>
 <Application>   
  <Connections>
   <AutoAccept>true</AutoAccept>
  <AllowDomains/>
  </Connections>
  <Streams>
   <StreamType>default</StreamType>
    <StorageDir>/C:/blah/flash/</StorageDir>
  </Streams>
  </Application>
  </Root>
EOT

doc.at('StorageDir').content = 'd:/path/to/foo'
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <Root>
# >>  <Application>   
# >>   <Connections>
# >>    <AutoAccept>true</AutoAccept>
# >>   <AllowDomains/>
# >>   </Connections>
# >>   <Streams>
# >>    <StreamType>default</StreamType>
# >>     <StorageDir>d:/path/to/foo</StorageDir>
# >>   </Streams>
# >>   </Application>
# >>   </Root>

也可以轻松覆盖原始文件。这是未经测试的,但看起来不错:

XML_FILE = 'path/to/xml'
doc = Nokogiri::XML(open(XML_FILE, 'r'))
doc.at('StorageDir').content = 'd:/path/to/foo'
File.write("#{ XML_FILE }.new", doc.to_xml)

注意,我没有覆盖原始文件,我正在写一个新文件。如果代码出现问题,例如修改错误的节点,这将保留旧文件而不是破坏其内容。

在生产系统中,您希望写入新文件,然后将旧文件重命名为安全文件,将新文件重命名为旧文件名,然后选择删除旧文件。 #39;确保一切正常。通过这样做,如果出现问题,你就可以了。