使用Nokogiri搜索XML文档的特定路径并更改它



使用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文件没有反映更改,您认为呢?

您需要给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 }

如果只有一个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)

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

在生产系统中,您可能希望写入一个新文件,然后将旧文件重命名为安全文件,将新文件重命名为旧文件的名称,然后在确定一切正常工作后,有选择地删除旧文件。

相关内容

  • 没有找到相关文章

最新更新