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.

[groovy language=”true”]
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.xmlDeclaration()
mkp.declareNamespace(ui: "http://java.sun.com/jsf/facelets",
h: "http://java.sun.com/jsf/html")
‘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’)
}
}
[/groovy]

And the output looks like this.
[xml language=”true”]
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" template="/layout/main.xhtml" xmlns:h="http://java.sun.com/jsf/html">
<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:form>
<h:commandButton id="formController_submit" action="#{formController.submit}" styleClass="submitButton" value="Submit"/>
</ui:composition>
[/xml]

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!

2 Responses to "StreamingMarkupBuilder for Groovy-er xml"

1 | John Wilson

July 27th, 2009 at 10:58 am

Avatar

The output does not seem to match the code fragment.

There’s no XML declaration in the output and the namespace http://java.sun.com/jsf/core is not declared in the code fragment.

2 | TheKaptain

July 27th, 2009 at 7:05 pm

Avatar

John is absolutely correct. I’ve updated the post and apologize for the hasty edit I did – the original sample actually had 6 namespaces and seemed a little overkill so I trimmed the code when pasting here on the blog.

Thanks for the CR John!

Comment Form