Monday, April 21, 2008

Groovy XMLSlurper

If you know anything about Groovy, I'm sure you have seen the XML parsing features it brings to the table. Whether you have seen it or not it is definitely worth mentioning. I feel this is a great tool added to my Java tool chest.

Imagine you have the following XML:

<basketball team="Kansas" status="National Champions">
<player>
<name>Brandon Rush</name>
<position>Small Forward</position>
<pts-per-game>13.5</pts-per-game>
<rebs-per-game>6.2</rebs-per-game>
</player>
<player>
<name>Mario Chalmers</name>
<position>Guard</position>
<pts-per-game>12.5</pts-per-game>
<rebs-per-game>4.2</rebs-per-game>
</player>
<player>
<name>Sherron Collins</name>
<position>Guard</position>
<pts-per-game>10.5</pts-per-game>
<rebs-per-game>3.4</rebs-per-game>
</player>
<player>
<name>Darrel Arthur</name>
<position>Power Forward</position>
<pts-per-game>14.2</pts-per-game>
<rebs-per-game>6.9</rebs-per-game>
</player>
<player>
<name>Darnell Jackson</name>
<position>Power Forward</position>
<pts-per-game>12.5</pts-per-game>
<rebs-per-game>8.9</rebs-per-game>
</player>
</basketball>


Now that you have your XML you want to parse it and put it into a Player object. Let's go ahead and create our Player object:


class Player {
String name
String position
double ptsPerGame
double rebsPerGame

def String toString() {
return "Name: ${name}\r\nPosition: ${position}\r\nPoints Per Game: ${ptsPerGame}\r\nRebs Per Game${rebsPerGame}"
}
}

Now that we have our Player class created, lets create a class that will consume the XML create a Player for each Player in the XML:


class ParsePlayers {
private List players

ParsePlayers () {
players = new ArrayList()
}

def Player[] parsePlayers() {
def data = this.getClass().getResource("/players.xml").text
def xmlSlurper = new XmlSlurper()
def playersXml = xmlSlurper.parseText(data)

playersXml.player.each {
def player = new Player()

player.name = it.name.text()
player.position = it.position.text()
player.ptsPerGame = Double.parseDouble(it.'pts-per-game'.text().trim())
player.rebsPerGame = Double.parseDouble(it.'rebs-per-game'.text().trim())

players.add(player)
}
return (Player[])players.toArray()
}
}


So, as you can see above that is a pretty simple way to parse XML using XMLSlurper from Groovy. I don't know about you, but that makes working with XML a little bit nicer.

5 comments:

Hamlet D'Arcy said...

The reason to use XMLSlurper instead of XMLParser is because it is less memory intensive. I'm not 100% sure on this, but I think XMLSlurper never holds the entire document in memory, it queries and pulls it as needed.

def data = this.getClass().getResource("/players.xml").text

will read the entire xml document as a string, so I think you'd be better off if you just used the parse(File) method instead of parseText(String) method. I could be wrong though.

tug said...

player.ptsPerGame = Double.parseDouble(it.'pts-per-game'.text().trim())

can also be written as

player.ptsPerGame = it.'pts-per-game'.toDouble()

Chad Gallemore said...

Thanks for the comment tug, great catch.

Nomesh said...

Nice Example, Thanks..
As I am new to Groovy I have a question.

If I want to get the value "Kansas"
from the root tag, how do I get it?

Nomesh said...

Nice Example, Thanks..
But I have a question since I am new to Groovy.

If I want to access a value from the root tag, let's say the value "Kansas", How can i do that?