Groovy markupBuilder обновляет родительский узел
Я строю XML с использованием MarkupBuilder и удивляюсь, как я могу обновить родительский атрибут при создании дочернего узла. Предполагая, что количество дочерних элементов не может быть рассчитано при построении родительского элемента.
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.parent(totalDuration: 'should be: some of all child duration') {
child(duration: '1')
child(duration: '2')
...
}
Есть ли элегантный способ доступа к родительскому узлу из дочернего узла?
Спасибо Тал
1 ответ
Есть ли элегантный способ доступа к родительскому узлу из дочернего узла?
Не с MarkupBuilder, который генерирует XML в потоковом режиме (он уже записал открывающий тег родительского элемента в выходной поток перед вызовом вложенного замыкания). Но вы можете использовать DOMBuilder для построения дерева DOM в памяти, затем заполнить итоговое значение с помощью DOM API и, наконец, сериализовать дерево DOM, включая атрибут total:
import groovy.xml.*
import groovy.xml.dom.*
import org.w3c.dom.*
def dom = DOMBuilder.newInstance(false, true)
Element parent = dom.parent() {
child(duration:'1')
child(duration:'2')
}
use(DOMCategory) {
parent.setAttributeNS(null, "totalDuration",
parent.xpath('sum(child/@duration)'))
}
def xmlString = XmlUtil.serialize(parent)
DOMBuilder должен работать так же, как и MarkupBuilder, если вы не используете mkp.yield
или же mkp.yieldUnescaped
внутри закрытия. Если вам нужно использовать их, вам придется создать строку XML без totalDuration
атрибута, затем повторно проанализируйте его в DOM, добавьте дополнительный атрибут и повторно сериализуйте.