Распечатать документ XML без строки заголовка XML вверху - PullRequest
10 голосов
/ 22 ноября 2011

Я просто пытаюсь выяснить, как сделать to_xml с Nokogiri::XML::Document или Nokogiri::XML::DocumentFragment.

В качестве альтернативы я хотел бы использовать xPath на Nokogiri::XML::DocumentFragment. Я не смог выяснить, как это сделать, однако я успешно разбираю Nokogiri::XML::Document.

Позже я включаю разобранный и модифицированный DocumentFragment в другой кусок XML, но я действительно укушен тем, что, как я думал, будет действительно очень простыми вещами.

Как попытка сделать to_xml для документа или документа, и НЕ ВКЛЮЧАТЬ эту строку xml вверху. Почему так сложно?

Ответы [ 2 ]

24 голосов
/ 22 ноября 2011

Самый простой способ получить XML для Document без начального "PI" ( инструкция обработки ) - это вызвать 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"/>

Если это так, и вы хотите избавиться от любых ПИ, вы можете сделать это , если сможет сделать это с небольшим XPath:

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

… за исключением того, что это не работает из-за странности с XPath в 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"/>
0 голосов
/ 16 июля 2015

Вот как это сделать в рельсах: 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"
...