Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 720
CodeVenture Avatar asked Aug 02 '13 06:08

CodeVenture


1 Answers

This contribution has helped me to solve a similar problem : I wanted to call functions in MarkupBuilder blocks, like the addElement() function in my example.

I wanted to split the code into different functions.

Example for calling functions in MarkupBuilder blocks :

static void addElement(Map<String,String> elements, MarkupBuilder mb) {
    mb."${elements.tag}"(elements.content)
}

static void example() {
    def writer = new StringWriter()
    def htmlBuilder = new MarkupBuilder(writer)

    String tag = "a"
    Map<String, String> attributes1 = new HashMap<>()
    attributes1.put("href","http://address")
    String content1 = "this is a link"

    Map<String, String> element1 = new HashMap<>()
    element1.put("tag","b")
    element1.put("content","bold content 1")

    Map<String, String> element2 = new HashMap<>()
    element2.put("tag","b")
    element2.put("content","bold content 2")

    List<Map<String, String>> elements = new ArrayList<>()
    elements.add(element1)
    elements.add(element2)

    htmlBuilder."html" {
        "${tag}"( attributes1, content1 )
        elements.each { contentIterator ->
            addElement(contentIterator, htmlBuilder)
        }
    }

    println writer
 }

and it produces this output :

<html>
  <a href='http://address'>this is a link</a>
  <b>bold content 1</b>
  <b>bold content 2</b>
</html>
like image 116
Andre Rolfs Avatar answered Nov 16 '22 02:11

Andre Rolfs