Converting xml to domain object in Grails
-
30-05-2021 - |
Question
I'm a grails newbie working on a project for fun. I'm serializing a class like this:
def msg = (listing as XML).toString()
the trying to deserialize a class using the XMLSlurper like this:
def root = new XmlSlurper().parseText(listingString)
def sellerNode = root.seller
I'm trying to reconstruct this object:
Listing{
Date dateCreated
String description
Date endDateTime
String name
Float startingPrice
Customer winner
static hasMany = [bids: Bid] // B-4
static belongsTo = [seller: Customer]
}
}
from this xml:
<?xml version="1.0" encoding="UTF-8"?>
<listing>
<bids>
<bid>
<amount>10.5</amount>
<bidder>
<accountExpired>false</accountExpired>
<accountLocked>false</accountLocked>
<dateCreated/>
<emailAddress>validguy@valid.com</emailAddress>
<enabled>false</enabled>
<password>secret</password>
<passwordExpired>false</passwordExpired>
<username>validguy</username>
</bidder>
<dateCreated>2012-04-08 21:16:41.423 CDT</dateCreated>
<listing/>
</bid>
<bid>
<amount>10.0</amount>
<bidder>
<accountExpired>false</accountExpired>
<accountLocked>false</accountLocked>
<dateCreated/>
<emailAddress>validguy@valid.com</emailAddress>
<enabled>false</enabled>
<password>secret</password>
<passwordExpired>false</passwordExpired>
<username>validguy</username>
</bidder>
<dateCreated>2012-04-08 21:16:41.415 CDT</dateCreated>
<listing/>
</bid>
</bids>
<dateCreated/>
<description>A test listing</description>
<endDateTime>2012-04-09 21:16:41.407 CDT</endDateTime>
<name>Default</name>
<seller>
<accountExpired>false</accountExpired>
<accountLocked>false</accountLocked>
<dateCreated/>
<emailAddress>validguy@valid.com</emailAddress>
<enabled>false</enabled>
<password>secret</password>
<passwordExpired>false</passwordExpired>
<username>validguy</username>
</seller>
<startingPrice>10.0</startingPrice>
<wasNotificationSent>false</wasNotificationSent>
<winner>
<accountExpired>false</accountExpired>
<accountLocked>false</accountLocked>
<dateCreated/>
<emailAddress>validguy@valid.com</emailAddress>
<enabled>false</enabled>
<password>secret</password>
<passwordExpired>false</passwordExpired>
<username>validguy</username>
</winner>
</listing>
First I'm having issues getting to the values of each node. I've tried def seller = new Customer(name:sellerNode.@username) but that doesn't work since I assume @username needs to be an attribute and not an element. Second, do I have to parse this xml "by hand"? Isn't there a better way to deserialize this xml automatically?
I already looked at a couple of posts and including this one: Import XML into a Grails Domain Class however as you can see, my xml doesn't have attributes like the xml in this post.
Thanks,
La solution
If the source of the XML is a web request, you can add parseRequest: true
to the UrlMapping for your controller, grails will parse the XML request automatically. The XML will be presented as params
and you can do data binding the same as any other request.
If you're getting the XML from another source, take a look at the XML to parameter map conversion in the class XMLParsingParameterCreationListener.groovy
.
Autres conseils
I did look at the class aTaylor suggested but due to time constraints I ended up parsing the xml with the slurper this way:
def listing = new XmlSlurper().parseText(listingXML)
def winner = listing."winner"."username".text()
I was constrained by the fact that I can only get at text values. For instance, I couldn't deserialize the bids elements into a collection and perform calculations like bids.Max(b->b.amount). That was my ultimate goal.
BTW - This is was not a web request. It was a MQ message serialized as xml.