【问题标题】:Print an XML document without the XML header line at the top打印顶部没有 XML 标题行的 XML 文档
【发布时间】:2015-12-10 23:07:22
【问题描述】:

我只是想了解如何将to_xmlNokogiri::XML::DocumentNokogiri::XML::DocumentFragment 联系起来。

或者,我想在 Nokogiri::XML::DocumentFragment 上使用 xPath。我无法确定如何执行此操作,但我成功解析了 Nokogiri::XML::Document

我稍后将经过解析和修改的DocumentFragment 包含到另一段 XML 中,但我真的被我认为非常简单的事情所困扰。

就像尝试在 doc 或 docfrag 上执行 to_xml 一样,并且不包括顶部的 xml 行。为什么这么难?

【问题讨论】:

  • 您的“问题”有点啰嗦。文档片段上的 XPath 与这个问题有什么关系?

标签: ruby xml nokogiri


【解决方案1】:

在没有前导“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"/>

 


请注意,DocumentFragments 不会自动包含此 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"/>

【讨论】:

  • 它曾经把我带到#attributes-i-&lt;something&gt; 而不是#attributes。现在看历史,我再也看不到那个参考了。如果这是我的错误,请忽略/撤消它。
  • 谢谢你,@onions;我已将您的发现添加到此答案中,并对您的答案和问题进行了投票。
  • 使用 NO_DECLARATION 会导致输出丢失所有格式,这很糟糕(换行和缩进)。
  • @aaa90210 感谢您指出这一点。所以你真正想要的是使用save_with: (Nokogiri::XML::Node::SaveOptions::NO_DECLARATION + Nokogiri::XML::Node::SaveOptions::FORMAT)...或者,非常丑陋,只是save_with:3
【解决方案2】:

这里是如何在 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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多