Объединить nokogiri по Строителей в XML


Мне нравится конструкция Nokogiri::XML::Builder, но было бы проще собирать большие XML-документы, если бы я мог модулировать процесс построения дальше, разделяя работу между несколькими строителями.

Кто-нибудь видит Способ заставить нескольких строителей сотрудничать? (например, родительский конструктор, вызывающий функции, которые позволяют дочерним конструкторам создавать меньшие части документа)

Или есть способ модифицировать конструктор после завершения его блока? (- - - если не считать вывода XML, затем разбираем его в документ Nokogiri:: XML::, затем добавляем узлы, затем снова выводим XML)

1 9

1 ответ:

Делегирование Функций Конструктора

например, родительский конструктор, вызывающий функции, которые задают дочерним конструкторам создавать меньшие части документа

Вы можете легко делегировать ответственность методам, которые принимают текущее состояние конструктора и используют его. Например:

require 'nokogiri'

def add_kids_for(name,xml)
  xml.send(name){ 1.upto(3){ |i| xml.kid("#{name}'s kid ##{i}") } }
end

build = Nokogiri::XML::Builder.new do |xml|
  xml.root do
    add_kids_for("Danny",xml)
    add_kids_for("Billy",xml)
  end
end
puts build.to_xml
#=> <?xml version="1.0"?>
#=> <root>
#=>   <Danny>
#=>     <kid>Danny's kid #1</kid>
#=>     <kid>Danny's kid #2</kid>
#=>     <kid>Danny's kid #3</kid>
#=>   </Danny>
#=>   <Billy>
#=>     <kid>Billy's kid #1</kid>
#=>     <kid>Billy's kid #2</kid>
#=>     <kid>Billy's kid #3</kid>
#=>   </Billy>
#=> </root>

Просто передайте xml (или как вы там называете свой объект builder) методу, и пусть этот метод делает то, что ему нужно (процедурно или вручную).

Изменение конструктора после создания

или есть способ изменить конструктор после завершения его блока?

Да! :) Вы хотите к doc методу строителя получить Nokogiri::XML::Document управляя им. Продолжая приведенный выше пример:

doc = build.doc
doc.css('kid').each do |kid|
  kid['name'] = %w[Bobby Jenny Jill Sam Gish Gavin Lisa Imogen Lachlan].sample
end
puts doc
#=> <root>
#=>   <Danny>
#=>     <kid name="Lisa">Danny's kid #1</kid>
#=>     <kid name="Imogen">Danny's kid #2</kid>
#=>     <kid name="Lachlan">Danny's kid #3</kid>
#=>   </Danny>
#=>   <Billy>
#=>     <kid name="Gish">Billy's kid #1</kid>
#=>     <kid name="Gavin">Billy's kid #2</kid>
#=>     <kid name="Sam">Billy's kid #3</kid>
#=>   </Billy>
#=> </root>