Skip to content

Instantly share code, notes, and snippets.

@robvalk
Created December 2, 2013 09:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robvalk/7747206 to your computer and use it in GitHub Desktop.
Save robvalk/7747206 to your computer and use it in GitHub Desktop.
Sample XML to XML data mapping using Groovy builders. Input and output are both w3c DOM object trees.
//import the GroovyMap
import au.com.sixtree.esb.mapper.GroovyMap
//We have a customized version of DOMCategory helper class, this provides us with xpath like features to access elements
//The default version involves a slightly different syntax.
import au.com.sixtree.java.esb.mapper.DOMCategory
//GroovyMap's toXMLDom() method takes input as the root/documentElement of the XML tree, type @Element
//very similar to accessing the root element in Java - payload.getDocumentElement()
return GroovyMap.toXmlDom(payload.documentElement) {
//inputs is a list of input arguments
def _in = inputs[0]
//Groovy provides a neat feature called use(TYPE){} closure using which you can retrieve xml elements using xpath style syntax
use(DOMCategory) {
/* map the root element with a namespace
The builder object is part of GroovyMap (of type NamespaceBuilder), which has a method called declareNamespace(namespace_map)
*/
builder.declareNamespace('en':'http://sixtree.com.au/system/inboundadapter/v1/xsd' , 'xsi':'http://www.w3.org/2001/XMLSchema-instance')
//Using the same builder object, construct the root element <en:getbookInventoryResponse>
builder.'en:getbookInventoryResponse' {
/*
* The below construct is trying to represent a <book> with its Inventory Status across various locations
* One book can be stocked at various locations
* */
book{
//If condition to check if the input xml contains an element called <identifier>
if(_in.book[0].identifier)
//This creates an identifier tag <identifier>12345</identifier>
//You can also use the element(value) style to achieve a similar result
//eg. identifier(_in.book[0].identifier)
identifier _in.book[0].identifier
if(_in.book[0].name)
name _in.book[0].name
/*Since one book can have multiple inventory locations and details, iterate over the inbound xml's inventoryDetails element list
Note the "inventoryDetails_tmp" identifier, its important you dont use same identifiers for input and output variables
Here inventoryDetails is present in both input and output xml, so while mapping to an output xml, ensure you are using a
different id for the variable (eg. inventoryDetails_tmp is used to iterate over the inbound inventoryDetails)
You wont notice this ambiguity until runtime.
*/
for(inventoryDetails_tmp in _in.book[0].inventoryDetails)
inventoryDetails{
status inventoryDetails_tmp.status
location{
city inventoryDetails_tmp.location.city
state inventoryDetails_tmp.location.state
}
inventoryCount inventoryDetails_tmp.inventoryCount
}
}
}
}
}.map()
//Calling the map, serializes (or marshals) the string to an xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment