Подтвердить что ты не робот

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>

Как это можно сделать? Спасибо заранее!

4b9b3361

Ответ 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",'')

Вероятно, проще, чем пытаться перегрузить метод.