如何使用 Nokogiri 压缩现有 XML

How to compact existing XML using Nokogiri

我正在尝试使用 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)

但这也不管用。

如何删除可忽略的空格?

好的,我回答我自己的问题。

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 文件有内联自关闭标签,并且只有空白文本节点在不应压缩的那些标签之间。我现在正试图找出一种方法来处理这种特殊情况。

您可以告诉 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"