How to recursively add a child inside StreamingMarkupBuilder

groovy, recursion, xml

Solution

Your Closure `addChildComponent` is still wrong in this case. Instad of passing "xml" (second) parameter to closure, you should set delegate to "parent" closure.

Example:

def components = ['component1', 'component2', 'component3', 'componentN']
def xmlBuilder = new StreamingMarkupBuilder();

//this is "outside" closure
def addComponent = { idx, text ->
    //this call is delegated to whatever we set: addComponent.delegate = xxxxxx
    component(order:idx, text)
}

def xmlString = xmlBuilder.bind{
    "root"(type:'tree', version:'1.0'){
        type('type')
        label('label')
        "child-components"{
            components.eachWithIndex{ obj, idx->
                //and delegate is set here
                addComponent.delegate = delegate
                addComponent(idx, obj)
            }
        }
    }
}.toString()

println XmlUtil.serialize(xmlString)

Output:

<?xml version="1.0" encoding="UTF-8"?>
<root type="tree" version="1.0">
  <type>type</type>
  <label>label</label>
  <child-components>
    <component order="0">component1</component>
    <component order="1">component2</component>
    <component order="2">component3</component>
    <component order="3">componentN</component>
  </child-components>
</root>

Hope you'll find this helpful.

Problem

I need to build a tree structure in xml where child element can have another child inside. Number of nested nodes is not specified. So I am using StreamingMarkupBuilder : ``` def rootNode = .... def xml = builder.bind { "root"(type:"tree", version:"1.0") { type(rootNode.type) label(rootNode.label) "child-components" { rootUse.components.each { comp -> addChildComponent(comp,xml) } } } ``` But I have problem creating proper addChildComponent method. Any ideas ? Edit : Ok I made it so : ``` def addChildComponent {comp,xml -> xml.zzz(){ "lala"() } } ``` but now I have problem with namespaces as I get : ``` <child-components> <xml:zzz> <lala/> </xml:zzz> <xml:zzz> <lala/> </xml:zzz> <xml:zzz> <lala/> </xml:zzz> </child-components> ``` thx

Original source