2017-07-16 56 views
0

我想使用Nokogiri壓縮現有的XML。我有以下的演示代碼:使用nokogiri的緊湊的現有XML

#!/usr/bin/env ruby 
require 'nokogiri' 

doc = Nokogiri.XML <<-XML.strip 
<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo> 
    <bar>test</bar> 
    </foo> 
</root> 
XML 

doc.write_xml_to($stdout, indent: 0) 

我期望看到

<?xml version="1.0" encoding="UTF-8"?> 
<root><foo><bar>test</bar></foo></root> 

而是我看到

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo> 
    <bar>test</bar> 
    </foo> 
</root> 

我已經試過

doc.write_to($stdout, indent: 0, save_with: Nokogiri::XML::Node::SaveOptions::AS_XML) 

但沒有按」不管工作。

如何刪除可忽略的空格?

+0

https://stackoverflow.com/questions/8406251/nokogiri-to-xml-without-carriage-returns可能幫幫我。如果你有很多級別的數據,我會建議sub,但它不可行。唯一能想到的是使用正則表達式,但是如果你在XML屬性或值中有很長的字符串,那麼這可能也不起作用。 – whodini9

+1

@ whodini9我沒有使用構建器,因爲我的最終目標是壓縮現有的XML文件。此外,根據Nokogiri的官方文檔和源代碼,'Node#write_xml_to'只需使用'save_with:DEFAULT_XML'選項調用'Node#write_to'。順便說一句,'AS_XML'是'DEFAULT_XML'的別名。 –

回答

0

好的,我回答我自己的問題。

Nokogiri不刪除空白,因爲Nokogiri不知道白色空格是否可以忽略(沒有DTD,沒有模式),所以它將所有隻有空白的文本保留爲文本節點。在將XML文檔寫入IO設備之前,我應手動刪除它們。

#!/usr/bin/env ruby 
require 'bundler' 
Bundler.require :default 

doc = Nokogiri.XML <<-XML.strip 
<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo> 
    <bar>test</bar> 
    </foo> 
</root> 
XML 

# remove ignorable white spaces 
doc.xpath('//text()').each do |node| 
    node.content = '' if node.text =~ /\A\s+\z/m 
end 

doc.write_xml_to($stdout, indent: 0) 

這是我的一大進步,但我還沒有達到我的目標,因爲我工作的XML文件具有內嵌自閉的標籤,還有那些之間的空白,只有文本節點不應壓縮的標籤。我試圖找出一種方法來處理這個角落案例。

0

你可以告訴引入nokogiri忽略空文本節點,然後輸出無壓痕:

require 'nokogiri' 

xml = <<EOT 
<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo> 
    <bar>test</bar> 
    </foo> 
</root> 
EOT 

doc = Nokogiri::XML(xml) { |opts| 
    opts.noblanks 
    opts.strict.noblanks 
} 
doc.to_xml(:indent_text => '', :indent => 0) 
# => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
# "<root>\n" + 
# "<foo>\n" + 
# "<bar>test</bar>\n" + 
# "</foo>\n" + 
# "</root>\n"