Nokogiri to_xml без возврата каретки
В настоящее время я использую класс Nokogiri:: XML:: Builder для создания XML-документа, а затем вызываю .to_xml. Получившаяся строка всегда содержит кучу пробелов, переводы строк и возврат каретки между узлами, и я не могу на всю жизнь понять, как избавиться от них. Вот пример:
b = Nokogiri::XML::Builder.new do |xml|
xml.root do
xml.text("Value")
end
end
b.to_xml
В результате получается следующее:
<?xml version="1.0"?>
<root>Value</root>
Я хочу это (обратите внимание на недостающую строку перевода):
<?xml version="1.0"?><root>Value</root>
Как это можно сделать? Спасибо заранее!
Ответы
Ответ 1
Builder#to_xml
по умолчанию выводит форматированный (то есть отложенный) XML. Вы можете использовать Nokogiri::XML::Node::SaveOptions
, чтобы получить почти неформатированный результат.
b = Nokogiri::XML::Builder.new do |xml|
xml.root do
xml.foo do
xml.text("Value")
end
end
end
b.to_xml
#=> "<?xml version=\"1.0\"?>\n<root>\n <foo>Value</foo>\n</root>\n"
b.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML)
#=> "<?xml version=\"1.0\"?>\n<root><foo>Value</foo></root>\n"
Теперь вы можете либо просто избавиться от заголовка XML (который в любом случае является необязательным) и удалить последнюю новую строку
b.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).strip
#=> "<root><foo>Value</foo></root>"
Просто удаление любых новых строк в XML, вероятно, является плохой идеей, поскольку новые строки могут быть значительными (например, в <pre>
блоках XHTML). Если это не так для вас (и вы действительно уверены в этом), вы могли бы просто сделать это.
Ответ 2
Это не то, что Nokogiri предназначен для этого. Самое близкое, что вы можете получить, - это сериализовать корень документа без новых строк или отступов, а затем добавить PI самостоятельно (если вам это действительно нужно):
require 'nokogiri'
b = Nokogiri::XML::Builder.new{ |xml| xml.root{ xml.foo "Value" } }
p b.to_xml
#=> "<?xml version=\"1.0\"?>\n<root>\n <foo>Value</foo>\n</root>\n"
p b.doc.serialize(save_with:0)
#=> "<?xml version=\"1.0\"?>\n<root><foo>Value</foo></root>\n"
flat_root = b.doc.root.serialize(save_with:0)
p flat_root
#=> "<root><foo>Value</foo></root>"
puts %Q{<?xml version="1.0"?>#{flat_root}}
#=> <?xml version="1.0"?><root><foo>Value</foo></root>
В качестве альтернативы вы можете просто обмануть и сделать:
puts b.doc.serialize(save_with:0).sub("\n","")
#=> <?xml version="1.0"?><root><foo>Value</foo></root>
Обратите внимание на использование sub
вместо gsub
, чтобы заменить только первую известную новую строку.
Ответ 3
b.to_xml
возвращает строку. Вам просто нужно заменить первый экземпляр \n
в строке.
require 'nokogiri'
b = Nokogiri::XML::Builder.new do |xml|
xml.root do
xml.text("Value")
end
end
b.to_xml.sub("\n",'')
Вероятно, проще, чем пытаться перегрузить метод.