插入标签时的Nokogiri和XML格式

mic*_*ael 8 ruby xml nokogiri

我想使用Nokogiri将节点插入到XML文档中.Nokogiri使用Nokogiri::XML::Builder该类来插入或创建新的XML.

如果我使用该new方法创建XML ,我可以创建漂亮的格式化XML:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.product {
    xml.test "hi"
  }
end

puts builder
Run Code Online (Sandbox Code Playgroud)

输出以下内容:

<?xml version="1.0"?>
<product>
  <test>hi</test>
</product>       
Run Code Online (Sandbox Code Playgroud)

这很好,我想要做的是将上面的XML添加到现有文档中,而不是创建新文档.根据Nokogiri文档,这可以通过使用Builder的with方法来完成,如下所示:

builder = Nokogiri::XML::Builder.with(document.at('products')) do |xml|
  xml.product {
    xml.test "hi"
  }
end

puts builder
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时,XML全部被放入一行而没有缩进.它看起来像这样:

<products><product><test>hi</test></product></products>
Run Code Online (Sandbox Code Playgroud)

我错过了什么让它格式正确吗?

mic*_*ael 11

在Nokogiri邮件列表中找到答案:

在XML中,空格可以被认为是有意义的.如果解析包含空白节点的文档,libxml2将假定空白节点是有意义的,不会为您插入它们.

通过将"noblanks"标志传递给解析器,可以告诉libxml2空白没有意义.为了演示,这里有一个例子来重现你的错误,然后做你想要的:

require 'nokogiri'
def build_from node
  builder = Nokogiri::XML::Builder.with(node) do|xml|
    xml.hello do
      xml.world
    end
  end
end

xml = DATA.read
doc = Nokogiri::XML(xml)
puts build_from(doc.at('bar')).to_xml
doc = Nokogiri::XML(xml) { |x| x.noblanks }
puts build_from(doc.at('bar')).to_xml
Run Code Online (Sandbox Code Playgroud)

输出:

<root>
  <foo>
    <bar>
      <baz />
    </bar>
  </foo>
</root>
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在Ruby 1.9下,您可以稍微简洁地指定单个noblanks标志:`doc = Nokogiri :: XML(xml,&:noblanks)` (6认同)