Grails and Groovy xml marshalling and unmarshalling
Converting JSON to a map object is a very simple task to perform in Groovy. But what if you need to marshal and unmarshal xml?
I will show a simple way on how to do it.
Suppose we have a reservation xml we want to marshal:
<ns2:roomReservation xmlns:ns2="http://an.address.com/"> <customerId locale="en_US">F3F0C7</customer> <itineraryId>205216012</itineraryId> <rooms> <room>301</room> <room>302</room> </rooms> <info> <start>2015-05-23</start> <end>2015-05-26</end> </info> </ns2:roomReservation>
Ok now we must define classes to marshal xml to. Let's define a RoomReservation groovy class which must implements Serializable
package com.test.a import javax.xml.bind.annotation.* @XmlRootElement(name="roomReservation", namespace="http://an.address.com/") @XmlAccessorType(XmlAccessType.FIELD) class RoomReservation implements Serializable { @XmlElement String customerId @XmlAttribute String locale @XmlElement long itineraryId @XmlElement(name="rooms") List<Room> roomList @XmlElement(name="info") Info info }
Let's have a look at this class: this class bind roomReservation tag to this class and maps all the fields within.
Any attribute is mapped by @XmlAttribute annotation and the rooms tag is mapped as a List (roomList groovy property).
Pay attention!!! Any time you define a non simple Object or type property, you must use (name="xmltag") to map it to your specific class such as for Info class and List.
Now let's have a look at our Info class:
package com.test.a import javax.xml.bind.annotation.* @XmlRootElement(name="info") @XmlAccessorType(XmlAccessType.FIELD) class Info implements Serializable { @XmlElement String start @XmlElement String end }
Now that we have mapped our structures, we can unmarshal xml this way:
String xml ... ... //we omit how to get xml but it will be stored in xml variable def jaxbContext= JAXBContext.newInstance(RoomReservation.class) def unmarshaller = jaxbContext.createUnmarshaller() RoomReservation roomReservation = unmarshaller.unmarshal(new StringReader(xml))
or marshal this way (using the RoomReservation already defined and populated):
def jaxbContext = JAXBContext.newInstance(RoomReservation.class) def marshaller = jaxbContext.createMarshaller() StringWriter writer = new StringWriter(); marshaller.marshal(roomReservation, writer) String xml = writer.toString()
So this is a very simple way to marshal and unmarshal xml to Groovy objects.