Nokogiri и XML форматирование при вставке тегов - PullRequest
8 голосов
/ 08 октября 2010

Я бы хотел использовать Nokogiri для вставки узлов в XML-документ. Nokogiri использует класс Nokogiri::XML::Builder для вставки или создания нового XML.

Если я создаю XML с использованием метода new, я могу создать красивый отформатированный XML:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.product {
    xml.test "hi"
  }
end

puts builder

выводит следующее:

<?xml version="1.0"?>
<product>
  <test>hi</test>
</product>       

Это здорово, , но я хочу добавить вышеуказанный XML к существующему документу, а не создавать новый документ. Согласно документации Nokogiri, это можно сделать с помощью метода with Строителя, например:

builder = Nokogiri::XML::Builder.with(document.at('products')) do |xml|
  xml.product {
    xml.test "hi"
  }
end

puts builder

Однако, когда я делаю это, все XML помещаются в одну строку без отступа. Это выглядит так:

<products><product><test>hi</test></product></products>

Я что-то упустил, чтобы правильно отформатировать?

1 Ответ

11 голосов
/ 08 октября 2010

Нашел ответ в списке рассылки Nokogiri:

В XML пробелами можно считать осмысленный. Если вы анализируете документ который содержит пробельные узлы, libxml2 будет предполагать, что пробел узлы имеют смысл и не будут вставьте их для вас.

Вы можете сказать libxml2, что пробел не имеет смысла, передавая Флаг noblanks для парсера. к продемонстрировать, вот пример, который воспроизводит вашу ошибку, а затем делает то, что Вы хотите:

require 'nokogiri'
def build_from node
  builder = Nokogiri::XML::Builder.with(node) do|xml|
    xml.hello do
      xml.world
    end
  end
end

xml = DATA.read
doc = Nokogiri::XML(xml)
puts build_from(doc.at('bar')).to_xml
doc = Nokogiri::XML(xml) { |x| x.noblanks }
puts build_from(doc.at('bar')).to_xml

Выход:

<root>
  <foo>
    <bar>
      <baz />
    </bar>
  </foo>
</root>
...