title: How to add dynamically node to XML in Groovy with the StreamingMarkupBuilder
body: <p>I am trying to dynamically create an XML file with Groovy. I'm pleased with the simplicity everything works, but i am having a hard time understanding the whole mechanism behind closures and delegates. While it appears to be easy to add properties and child nodes with a fixed name, adding a node with a dynamic name appears to be a special case.</p>
  
  <p>My use case is creating a _rep_policy file, which can be used in CQ5.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
            jcr:primaryType="rep:ACL"&gt;
    &lt;allow
        jcr:primaryType="rep:GrantACE"
        rep:principalName="administrators"
        rep:privileges="{Name}[jcr:all]"/&gt;
    &lt;allow0
        jcr:primaryType="rep:GrantACE"
        rep:principalName="contributor"
        rep:privileges="{Name}[jcr:read]"/&gt;
  &lt;/jcr:root&gt;
  </code></pre>
  
  <p>Processing the collections works fine, but generating the name ...</p>
  
  <p>import groovy.xml.StreamingMarkupBuilder
      import groovy.xml.XmlUtil</p>
  
  <pre><code>def _rep_policy_files = [
      '/content': [ // the path
          'deny': [ // permission
              'jcr:read': [ // action
                  'a1', 'b2']], // groups
          'allow': [
              'jcr:read, jcr:write': [
                  'c2']
          ]
      ]
  ]
  
  def getNodeName(n, i) {
    (i == 0) ? n : n + (i - 1)
  }
  
  _rep_policy_files.each {
    path, permissions -&gt;
      def builder = new StreamingMarkupBuilder();
  
      builder.encoding = "UTF-8";
  
      def p = builder.bind {
        mkp.xmlDeclaration()
  
        namespaces &lt;&lt; [
            jcr: 'http://www.jcp.org/jcr/1.0',
            rep: 'internal'
        ]
  
        'jcr:root'('jcr:primaryType': 'rep:ACL') {
          permissions.each {
            permission, actions -&gt;
              actions.each {
                action, groups -&gt;
                  groups.eachWithIndex {
                    group, index -&gt;
                      def nodeName = getNodeName(permission, index)
                      "$nodeName"(
                          'jcr:primaryType': 'rep:GrantACE',
                          'rep:principalName': "$group",
                          'rep:privileges': "{Name}[$action]")
                  }
              }
          }
        }
      }
  
      print(XmlUtil.serialize(p))
  }
  </code></pre>