2009-09-24 3 views
4

Я понимаю, как создать XML в Groovy с помощью MarkupBuilder. Как добавить/вставить элементы в объект MarkupBuilder после первоначального создания? Например, начните с:Добавить/вставить элементы в объект Groovy MarkupBuilder после первоначального создания

def builder = new MarkupBuilder(writer) 
    def items = builder.items{ 
     item(name: "book") 
    } 

Что бы произвести:

<items> 
    <item name="book/> 
</items> 

Я пытаюсь создать расширяемую сообщение базы XML, используя базовый класс, чтобы обернуть строителем и наследование, чтобы добавить специфические теги. Основываясь на приведенном выше примере, вот мой базовый класс:

Class ItemBuilder{ 
    def name; 
    def builder = new MarkupBuilder(writer) 
    public Object getXML(){ 
    def items = builder.items{ 
      item(name: this.name) 
     } 
    return items; 
    } 
} 

Вот пример расширенного строитель сообщения:

Class SubItemBuilder extends ItemBuilder{ 
     def type; 

     public Object getXML(){ 
     def items = super.getXML(); 
     //do something here to add a subitem child tag.... 
     return items; 
     } 
    } 

Если бы я работал с JSON в JavaScript, я хотел бы сделать что-то вроде:

items.item.subitem = "foo" 

я в конечном счете хочу SubItemBuilder.getXML генерировать:

<items> 
    <item name="book> 
     <subitem type="paperback"/> 
     </item> 
</items> 

Есть ли простой способ достичь этого? Похоже, что один из вариантов заключается в подклассе MarkupBuilder и добавлении общедоступных методов для вставки дочерних узлов. Есть ли лучший подход к достижению результата, который я ищу?

ответ

6

Пример поваренной книги Использование MarkupBuilder for Agile XML Creation показывает, как создать что-то близкое к тому, что мне нужно.

Например:

import groovy.xml.MarkupBuilder 

def writer = new StringWriter() 
def builder = new MarkupBuilder(writer) 

def subitem (builder){ 
    builder.subitem(type: "paperback") 
} 


def items = builder.items{ 
    item(name: "book") 
    subitem(builder) 
} 

println writer.toString()​ 
+0

Я понимаю, что этот ответ довольно старый, но было бы полезно, если бы вы предоставили фрагмент кода, который решил вашу проблему. Страница, с которой вы связаны, довольно длинная и содержит в ней _lot_ кода. +1 для вашего Q и -1 для этого A. – nickdos

+0

@nickdos Я добавил фрагмент кода – elevine

3

Я не знаю ответа, но я предлагаю вам реструктурировать попытку.

Как правило, либо (а) все выходные данные известны во время создания строителя, либо (б) программа работает в рамках закрытия застройщика. Я не видел строителя, используемого в качестве документа как такового.

Есть еще один вариант: StreamingMarkupBuilder. Этот класс не создает документ, пока он не будет передан писателю (т. Е. Асинхронный). Это также делает его легче построить документ из нескольких источников, как показано здесь:

import groovy.xml.* 

def builder = new StreamingMarkupBuilder() 

def item1 = { item(name:'book') } 
def item2 = { item(name:'mag') } 

def doc = { 
    "items" { 
     out << item1 
     out << item2 
    } 
} 

println builder.bind(doc) 

>>> <items><item name='book'/><item name='mag'/></items> 

Я не думаю, что это решит вашу проблему, хотя. Можете ли вы перефразировать вопрос с меньшим объемом? Таким образом, мы могли бы увидеть, есть ли философская проблема с большей картиной.

+0

Я отредактировал мой первоначальный вопрос и добавил больше деталей. Ваш ответ кажется, что он идет в правильном направлении, но все еще не совсем то, что мне нужно. Спасибо за помощь! – elevine

Смежные вопросы