Search code examples
xmldomgroovymarkup

Add/insert elements into Groovy MarkupBuilder object after initial creation


I understand how to create XML in Groovy using MarkupBuilder. How do you add/insert elements into a MarkupBuilder object after the initial creation? For example, start with:

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

Which would produce:

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

I am trying to create an extensible base XML message, using a core class to wrap the builder and inheritance to add specific tags. Building on the above example, here is my base class:

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

Here is an example extended message builder:

Class SubItemBuilder extends ItemBuilder{
       def type;

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

If I was working with JSON in JavaScript, I would do something like:

items.item.subitem = "foo"

I ultimately want SubItemBuilder.getXML to generate:

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

Is there any easy way to achieve this? Seems like one option is to subclass MarkupBuilder and add public methods to insert child nodes. Is there a better approach to achieve the result I'm looking for?


Solution

  • The cookbook example Using MarkupBuilder for Agile XML Creation shows how to create something close to what I need.

    For example:

    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()​