Created
December 2, 2013 09:44
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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