Как динамически добавить узел в XML в Groovy с помощью StreamingMarkupBuilder

Я пытаюсь динамически создать XML-файл с Groovy. Я доволен простотой, с которой все работает, но мне трудно понять весь механизм закрытия и делегатов. Хотя кажется, что добавить свойства и дочерние узлы с фиксированным именем очень просто, добавление узла с динамическим именем представляется особым случаем.

Мой пример использования - создание файла _rep_policy, который можно использовать в CQ5.

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
          jcr:primaryType="rep:ACL">
  <allow
      jcr:primaryType="rep:GrantACE"
      rep:principalName="administrators"
      rep:privileges="{Name}[jcr:all]"/>
  <allow0
      jcr:primaryType="rep:GrantACE"
      rep:principalName="contributor"
      rep:privileges="{Name}[jcr:read]"/>
</jcr:root>

Обработка коллекций работает нормально, но генерирует имя...

импорт groovy.xml.StreamingMarkupBuilder импорт groovy.xml.XmlUtil

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 ->
    def builder = new StreamingMarkupBuilder();

    builder.encoding = "UTF-8";

    def p = builder.bind {
      mkp.xmlDeclaration()

      namespaces << [
          jcr: 'http://www.jcp.org/jcr/1.0',
          rep: 'internal'
      ]

      'jcr:root'('jcr:primaryType': 'rep:ACL') {
        permissions.each {
          permission, actions ->
            actions.each {
              action, groups ->
                groups.eachWithIndex {
                  group, index ->
                    def nodeName = getNodeName(permission, index)
                    "$nodeName"(
                        'jcr:primaryType': 'rep:GrantACE',
                        'rep:principalName': "$group",
                        'rep:privileges': "{Name}[$action]")
                }
            }
        }
      }
    }

    print(XmlUtil.serialize(p))
}

1 ответ

Это то, что вы ищете?

'jcr:root'('jcr:primaryType': 'rep:ACL') {
    _rep_policy_files['/content'].each {k, v ->
       if(k == 'allow')
           "$k"('jcr:primaryType': 'rep:GrantACE', 
                'rep:principalName': 'administrators', 
                'rep:privileges': "$v"  ){}
       if(k == 'deny')
           "$k"('jcr:primaryType': 'rep:GrantACE', 
                'rep:principalName': 'contributor', 
                'rep:privileges': "$v"  ){}
    }
}

Результирующий xml, показанный в вопросе, не может быть правильно воспринят с тем, что у вас есть в _rep_policy_files,

Другие вопросы по тегам