10

我喜欢这个Nokogiri::XML::Builder结构,但是如果我可以通过在几个构建器之间拆分工作来进一步模块化构建过程,那么组装大型 XML 文档会更容易。

有没有人看到让多个建筑商合作的方法?(例如,父构建器调用设置子构建器以创建文档的较小部分的函数)

或者有没有办法在它的块终止后修改构建器?(---缺少输出XML,然后将其解析为Nokogiri::XML::Document,然后添加节点,然后再次输出XML)

4

1 回答 1

16

Delegating Builder Functionality

for instance, a parent builder calling functions that set child builders to create smaller portions of the document

You can easily delegate responsibility to methods that take the builder's current state and use it. For example:

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>

Just pass the xml (or whatever you call your builder object) to the method and let that method do what it needs to (either procedurally or manually).

Modifying a Builder after Creation

Or is there a way to modify a builder after its block terminates?

Yes! :) You want to the doc method of the Builder to get the Nokogiri::XML::Document driving it. Carrying on the above example:

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>
于 2012-07-24T22:30:18.837 回答