April 25, 2010

Groovy Goodness: Refactor XML Creation with StreamingMarkupBuilder

On Groovy's website we can find the article Using MarkupBuilder for Agile XML creation. Here we read how we create parts of the XML in separate methods, so we don't have to repeat ourselves if we are building XML. In this blog post we see a small example applying the same principles, but now we use StreamingMarkupBuilder. For the StreamingMarkupBuilder we must pass a closure to the bind() method. The closure contains a reference to the builder and we can use it in methods to define parts of the XML.

import groovy.xml.*

def markupBuilder = new StreamingMarkupBuilder()
def xml = markupBuilder.bind { builder ->
 client {
  name 'mrhaki'
  fullName 'Hubert A. Klein Ikkink'
  buildAddress builder, 'Main St.', 42, 'Ducktown'
  delivery {
      buildAddress builder, 'Main Av.', 101, 'Springfield'
      remarks 'During office hours'
  buildItems builder

def buildAddress(builder, streetName, number, city) {
 builder.address {
  street streetName
  houseNumber number
  buildCity builder, city

def buildCity(builder, city) {
 builder.city city

def buildItems(builder) {
    builder.items {
     ['iPod', 'eBook'].eachWithIndex { product, index ->
      item(id: index + 1) {
       name "Item $product"

assert '''<?xml version="1.0" encoding="UTF-8"?>
  <fullName>Hubert A. Klein Ikkink</fullName>
    <street>Main St.</street>
      <street>Main Av.</street>
    <remarks>During office hours</remarks>
    <item id="1">
      <name>Item iPod</name>
    <item id="2">
      <name>Item eBook</name>
''' == XmlUtil.serialize(xml)