Adding multiple XML elements/containers dynamically using XML MarkupBuilder in Groovy

CodeVenture picture CodeVenture · Aug 2, 2013 · Viewed 11.6k times · Source

I am trying to generate XML using Groovy MarkupBuilder.

XML needed is of this form (simplified):

<Order>
  <StoreID />
  <City />
  <Items>
    <Item>
      <ItemCode />
      <UnitPrice />
      <Quantity />
    </Item>
  </Items>
</Order>

The data is stored in an Excel file and is easily accessible. My Groovy script parses the Excel and generates the XML.

e.g.

import groovy.xml.*
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)

xml.Order{
  StoreID("Store1")
  City("New York")
  Items(){
    Item(){
      ItemCode("LED_TV")
      UnitPrice("800.00")
      Quantity("2")
    }
  }
}

There can be multiple "item" containers inside "items".

My question is: Let's say we want to generate Order XML having 10 items. Is there a way to write something like a for loop inside "items" container? That way, we won't need to write MarkupBuilder code for 10 different items.

There is a similar question Adding dynamic elements and attributes to groovy MarkupBuilder or StreamingMarkupBuilder. But it doesn't discuss looping.

Answer

dmahapatro picture dmahapatro · Aug 2, 2013

Yes there is a way of using loop. Extending your example here:

import groovy.xml.*
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)

//List of items represented as a map
def items = [[itemCode: "A", unitPrice: 10, quantity: 2], 
             [itemCode: "B", unitPrice: 20, quantity: 3], 
             [itemCode: "C", unitPrice: 30, quantity: 4], 
             [itemCode: "D", unitPrice: 40, quantity: 6], 
             [itemCode: "E", unitPrice: 50, quantity: 5]]

xml.Order{
  StoreID("Store1")
  City("New York")
  Items{
    //Loop through the list.
    //make sure you are using a variable name instead of using "it"
    items.each{item->
      Item{
        ItemCode(item.itemCode)
        UnitPrice(item.unitPrice)
        Quantity(item.quantity)
      }
    }
  }
}

println writer

Should give you what you are expecting.