The Kaptain on … stuff

26 Jul, 2009

StreamingMarkupBuilder for Groovy-er xml

Posted by: TheKaptain In: Development

Been having an awful lot of fun lately playing with the Groovy StreamingMarkupBuilder. I’m not a big fan of xml in general, but it’s definitely got its uses(configuration and web service data interchange to name just a couple).

StreamingMarkBuilder makes it really very painless to create complex xml structures without a whole lot of hassle. There are some excellent examples out there already, but I couldn’t find one offhand that put all the pieces together.

This example demonstrates how to include the xml declaration, set the encoding, and incorporate namespaces. It also shows how to use iteration to create nodes in the Document. The (somewhat contrived) example code shows one possible way to template Facelet forms based on some simple parameters.

import groovy.xml.StreamingMarkupBuilder

def inputs = ['FirstName', 'LastName', 'Street', 'City', 'Country']
def controller = 'formController'
def bean = 'formBean'

def builder = new StreamingMarkupBuilder()
builder.encoding = "UTF-8"
def doc = builder.bind {
    mkp.declareNamespace(ui: "",
            h: "")
    'ui:composition'(template: '/layout/main.xhtml') {
        'h:form'(id: "${controller}_form") {
            inputs.each {input ->
                def inputId = input.toLowerCase().replaceAll(' ', '')
                'h:outputLabel'(input, id: inputId, styleClass: 'inputlabel')
                'h:inputText'(id: "${inputId}_input", value: "${bean}_$inputId", styleClass: 'inputText')
        'h:commandButton'(id: "${controller}_submit", action: "#{${controller}.submit}", styleClass: "submitButton",
                value: 'Submit')

And the output looks like this.

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns:ui="" template="/layout/main.xhtml" xmlns:h="">
  <h:form id="formController_form">
    <h:outputLabel id="firstname" styleClass="inputlabel">FirstName</h:outputLabel>
    <h:inputText id="firstname_input" value="formBean_firstname" styleClass="inputText"/>
    <h:outputLabel id="lastname" styleClass="inputlabel">LastName</h:outputLabel>
    <h:inputText id="lastname_input" value="formBean_lastname" styleClass="inputText"/>
    <h:outputLabel id="street" styleClass="inputlabel">Street</h:outputLabel>
    <h:inputText id="street_input" value="formBean_street" styleClass="inputText"/>
    <h:outputLabel id="city" styleClass="inputlabel">City</h:outputLabel>
    <h:inputText id="city_input" value="formBean_city" styleClass="inputText"/>
    <h:outputLabel id="country" styleClass="inputlabel">Country</h:outputLabel>
    <h:inputText id="country_input" value="formBean_country" styleClass="inputText"/>
  <h:commandButton id="formController_submit" action="#{formController.submit}" styleClass="submitButton" value="Submit"/>

Normally StreamingMarkupBuilder output is devoid of whitespace but for readability I rendered it using the very handy example provided here. Big thank you to Jeff Sheets for sharing that code!

Get Adobe Flash player