2011-12-06 54 views
17

我目前使用Nokogiri :: XML :: Builder类来构造一个XML文档,然后调用它.to_xml。结果字符串总是在节点之间包含一堆空格,换行符和回车符,而且我不能为了我的生活找出如何摆脱它们。这里有一个例子:Nokogiri to_xml无回车返回

b = Nokogiri::XML::Builder.new do |xml| 
    xml.root do 
    xml.text("Value") 
    end 
end 

b.to_xml 

这导致以下:

<?xml version="1.0"?> 
<root>Value</root> 

我想是这样的(注意缺少的换行符):

<?xml version="1.0"?><root>Value</root> 

如何才能做到这一点?提前致谢!

回答

29

Builder#to_xml默认输出格式化(即缩进)的XML。您可以使用Nokogiri::XML::Node::SaveOptions来获得几乎未格式化的结果。

b = Nokogiri::XML::Builder.new do |xml| 
    xml.root do 
    xml.foo do 
     xml.text("Value") 
    end 
    end 
end 

b.to_xml 
#=> "<?xml version=\"1.0\"?>\n<root>\n <foo>Value</foo>\n</root>\n" 

b.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML) 
#=> "<?xml version=\"1.0\"?>\n<root><foo>Value</foo></root>\n" 

现在你既可以刚刚摆脱XML头(这是可选反正),并删除最后一个换行符

b.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip 
#=> "<root><foo>Value</foo></root>" 

只是在XML删除任何换行符可能是一个糟糕的主意,因为新行实际上可能很重要(例如,在<pre> XHTML块中)。如果你的情况不是这样(你确实确信这一点),你可以做到这一点。

+0

不幸的是,我被卡住使用Nokogiri v1.3.3,它不允许任何参数传递给to_xml。否则,这将是一个很好的解决方案。 – Cameron

+1

好吧,明白了。看起来你可以通过传递保存选项来序列化而不是to_xml来使用这种方法: – Cameron

+2

我的最终解决方案看起来像这样: 'builder.doc.serialize(:save_with => Nokogiri :: XML :: Node :: SaveOptions :: AS_XML).sub(“\ n”,“”).strip' – Cameron

3

这不是Nokogiri设计的目的。你可以得到的最接近的是序列化,没有换行或缩进文档的根,然后添加自己的PI(如果你真的需要它):

require 'nokogiri' 

b = Nokogiri::XML::Builder.new{ |xml| xml.root{ xml.foo "Value" } } 
p b.to_xml 
#=> "<?xml version=\"1.0\"?>\n<root>\n <foo>Value</foo>\n</root>\n" 

p b.doc.serialize(save_with:0) 
#=> "<?xml version=\"1.0\"?>\n<root><foo>Value</foo></root>\n" 

flat_root = b.doc.root.serialize(save_with:0) 
p flat_root 
#=> "<root><foo>Value</foo></root>" 

puts %Q{<?xml version="1.0"?>#{flat_root}} 
#=> <?xml version="1.0"?><root><foo>Value</foo></root> 

或者,你可以简单地欺骗和做:

puts b.doc.serialize(save_with:0).sub("\n","") 
#=> <?xml version="1.0"?><root><foo>Value</foo></root> 

sub代替gsub仅使用替换第一已知本换行符。

+0

这个解决方案几乎和接受的一样 - 谢谢! – Cameron

-1

b.to_xml返回一个字符串。您只需要替换字符串中的第一个\n实例。

require 'nokogiri' 

b = Nokogiri::XML::Builder.new do |xml| 
    xml.root do 
    xml.text("Value") 
    end 
end 

b.to_xml.sub("\n",'') 

可能比尝试重载方法更容易。

+2

只替换第一个\ n将不起作用 - 我实际创建的文档深层次很多,并且每个节点之后都有一个\ n。节点中的一些文本也包含\ n字符,我必须保留这些字符(这是针对Android的,它需要Java风格的字符串)。 – Cameron