我正在尝试编辑
XML文件并用ruby变量替换字符串.
现在这是我的代码:
现在这是我的代码:
<?xml version="1.0" encoding="US-ASCII"?> <Standart-Profile> <class1> <class2> <class3> <value1>old_A</value2> <value1>old_B</value2> <value1>old_C</value2> </class3> </class2> </class1> </Standart-Profile>
这是Ruby文件:
require "rexml/text" require 'rexml/document' include REXML def generate_2 ... end def generate_1 ... end File.open('Standart-Profile.xml') do |config_file| config = Document.new(config_file) config.root.elements['old_A'].text = 'generate_1' config.root.elements['old_B'].text = 'generate_2' config.root.elements['old_C'].text = 'generate_1' formatter = REXML::Formatters::Default.new File.open('New-Profile.xml','w') do |result| formatter.write(config,result) end end
但我一直收到这个错误:
Final-Tool-Kit.rb:19:in `block in <main>': undefined method `text=' for nil:NilC lass (NoMethodError) from test.rb:16:in `open' from test.rb:16:in `<main>'
解决方法
您的问题是,当您要查找文本内容为old_A的元素时,您正在寻找名为old_A的元素.
这是使用Nokogiri的解决方案,我发现它比REXML更方便:
require 'nokogiri' # gem install nokogiri xml = "<Standart-Profile> <class1> <class2> <class3> <value1>old_A</value2> <value1>old_B</value2> <value1>old_C</value2> </class3> </class2> </class1> </Standart-Profile>" doc = Nokogiri.XML(xml) doc.at('//text()[.="old_A"]').content = 'generate_1' doc.at('//text()[.="old_B"]').content = 'generate_2' doc.at('//text()[.="old_C"]').content = 'generate_3' File.open('output.xml','w') do |f| f.puts doc end #=> <?xml version="1.0" encoding="US-ASCII"?> #=> <Standart-Profile> #=> <class1> #=> <class2> #=> <class3> #=> <value1>generate_1</value1> #=> <value1>generate_2</value1> #=> <value1>generate_3</value1> #=> </class3> #=> </class2> #=> </class1> #=> </Standart-Profile>
如果您确实想要调用generate_1方法(如您所定义的那样),那么您将使用:
...content = generate_1 # no quotes
编辑:这是在REXML中使用XPath执行此操作的一种方法(在我将源XML修复为有效之后):
require 'rexml/document' doc = REXML::Document.new(xml) REXML::XPath.first(doc,'//*[text()="old_A"]').text = 'generate_1' REXML::XPath.first(doc,'//*[text()="old_B"]').text = 'generate_2' REXML::XPath.first(doc,'//*[text()="old_C"]').text = 'generate_3' puts doc #=> <Standart-Profile> #=> <class1> #=> <class2> #=> <class3> #=> <value1>generate_1</value1> #=> <value1>generate_2</value1> #=> <value1>generate_3</value1> #=> </class3> #=> </class2> #=> </class1> #=> </Standart-Profile>