如何在StreamingMarkupBuilder中递归添加子项

时间:2012-06-04 11:03:41

标签: xml recursion groovy

我需要在xml中构建一个树结构,其中子元素可以在其中包含另一个子元素。未指定嵌套节点数。所以我使用的是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)
            }
           }

  }

但是我在创建正确的addChildComponent方法时遇到了问题。有什么想法吗?

编辑:好的,我做到了:

def addChildComponent {comp,xml -> 
xml.zzz(){
    "lala"()
    }
}

但是现在我遇到名称空间问题:

<child-components>
<xml:zzz>
  <lala/>
</xml:zzz>
<xml:zzz>
  <lala/>
</xml:zzz>
<xml:zzz>
  <lala/>
</xml:zzz>
</child-components>

THX

1 个答案:

答案 0 :(得分:6)

在这种情况下你的关闭addChildComponent仍然是错误的。 将“xml”(第二个)参数传递给闭包的Instad,你应该将委托设置为“父”闭包。

示例:

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)

输出:

<?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>

希望你会发现这有用。