在顶部没有XML标题行的情况下打印XML文档

时间:2011-11-21 21:22:41

标签: ruby xml nokogiri

我只想了解如何使用to_xmlNokogiri::XML::DocumentNokogiri::XML::DocumentFragment

或者,我想在Nokogiri::XML::DocumentFragment上使用xPath。我无法确定如何做到这一点,但我成功地解析了Nokogiri::XML::Document

我后来将一个已解析和修改过的DocumentFragment包含在另一段XML中,但我真的对我认为会是一些非常简单的事情感到厌烦。

就像尝试在doc或docfrag上执行to_xml,而不是在顶部包含xml行。为什么这么难?

2 个答案:

答案 0 :(得分:24)

在没有前导“PI”(processing instruction)的情况下获取Document的XML的最简单方法是在根元素而不是文档本身上调用to_s

require 'nokogiri'
doc = Nokogiri.XML('<hello world="true" />')

puts doc
#=> <?xml version="1.0"?>
#=> <hello world="true"/>

puts doc.root
#=> <hello world="true"/>

但是,在文档或构建器级别执行此操作的“正确”方法是使用SaveOptions

formatted_no_decl = Nokogiri::XML::Node::SaveOptions::FORMAT +
                    Nokogiri::XML::Node::SaveOptions::NO_DECLARATION

puts doc.to_xml( save_with:formatted_no_decl )
#=> <hello world="true"/>

# Making your code shorter, but horribly confusing for future readers
puts doc.to_xml save_with:3
#=> <hello world="true"/>


请注意,DocumentFragment会自动包含此PI:

frag = Nokogiri::XML::DocumentFragment.parse('<hello world="true" />')
puts frag
#=> <hello world="true"/>

如果您在片段输出中看到PI,则表示在解析它时它就在那里。

xml = '<?xml version="1.0"?><hello world="true" />'
frag = Nokogiri::XML::DocumentFragment.parse(xml)
puts frag
#=> <?xml version="1.0"?><hello world="true"/>

如果是这样,并且你想摆脱任何PI,你可以这样做 能够通过一点XPath来实现:

frag.xpath('//processing-instruction()').remove
puts frag

... this does not appear to work除了oddness with XPath in DocumentFragments。要解决这些错误,请执行以下操作:

# To remove only PIs at the root level of the fragment
frag.xpath('processing-instruction()').remove
puts frag
#=> <hello world="true"/>

# Alternatively, to remove all PIs everywhere, including inside child nodes
frag.xpath('processing-instruction()|.//processing-instruction()').remove


如果您有Builder个对象,请执行以下任一操作:

builder = Nokogiri::XML::Builder.new{ |xml| xml.hello(world:"true") }

puts builder.to_xml
#=> <?xml version="1.0"?>
#=> <hello world="true"/>

puts builder.doc.root.to_xml
#=> <hello world="true"/>

formatted_no_decl = Nokogiri::XML::Node::SaveOptions::FORMAT +
                    Nokogiri::XML::Node::SaveOptions::NO_DECLARATION

puts builder.to_xml save_with:formatted_no_decl
#=> <hello world="true"/>

答案 1 :(得分:0)

以下是如何在rails中执行此操作:skip_instruct: true

 ['array of', 'strings'].to_xml skip_instruct: true, skip_types: true

 => "<strings>\n  <string>array of</string>\n  <string>strings</string>\n</strings>\n"