使用libxml在Ruby中找到元素后删除元素

时间:2014-08-07 19:30:07

标签: ruby xml xml-parsing libxml-ruby

我来自C背景,但在Ruby中处理与XML相关的一些事情,所以,如果我的问题很幼稚,请耐心等待。

我有一个XML文档。我正在使用libxml解析它:

<test>
 <ready>
  <ex_success>true</ex_success>
 </ready>
 <ath>
  <name>abc</name>
  <pass>123</pass>
  <ex_success>true</ex_success>
 </ath>
</test>

在本文档中,我可以阅读ex_success元素。但是,我无法从原始文件中删除它。

这是我的一小段代码:

require 'xml'
test_file = @file_name
parser = XML::Parser.file(test_file)
document = parser.parse

document.root.each_element {|element|

  # Write each element name in the file
  puts 'element.name'

  if val = element.find_first('ex_success')   
    puts val.content   # prints true
    val.remove!    # THIS line does not remove the element from my original file

  else
    puts 'Not found'
  end

我做错了什么以及删除它的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

我建议不要使用libxml。虽然它是Ruby的一部分,但它并不是Ruby的XML解析的事实标准。 Nokogiri是。

以下是我使用Nokogiri的方式:

require 'nokogiri'

doc = Nokogiri::XML::DocumentFragment.parse(<<EOT)
<test>
 <ready>
  <ex_success>true</ex_success>
 </ready>
 <ath>
  <name>abc</name>
  <pass>123</pass>
  <ex_success>true</ex_success>
 </ath>
</test>
EOT

ex_success = doc.at('ex_success')
ex_success_value = ex_success.text # !> assigned but unused variable - ex_success_value
ex_success.remove

puts doc.to_xml
# >> <test>
# >>  <ready>
# >>   
# >>  </ready>
# >>  <ath>
# >>   <name>abc</name>
# >>   <pass>123</pass>
# >>   <ex_success>true</ex_success>
# >>  </ath>
# >> </test>

如果您不希望空文本节点留下空行,请使用:

ex_success = doc.at('ex_success')
ex_success_value = ex_success.text # => "true"
ex_success.parent.children.remove

puts doc.to_xml
# >> <test>
# >>  <ready/>
# >>  <ath>
# >>   <name>abc</name>
# >>   <pass>123</pass>
# >>   <ex_success>true</ex_success>
# >>  </ath>
# >> </test>

我使用了Nokogiri::XML::DocumentFragment.parse,它按原样接受XML代码段。使用Nokogiri::XML(<<EOT)更常见,如果不存在,则会添加XML decl。