Monday, February 05, 2007

Flattening Xml to Map using depthFirst

It's very wonderful and extremely easy to use groovy.xml.XmlParser to flatten an XML document into a Grails compatible Map:


def Map xmlToMap(String xml) {
def root = new XmlParser().parseText(xml)
def map = [:]
root.depthFirst().each { n ->
if(n.value.size == 1) {
def key = n.name
def p = n.parent
while(p.parent != null) {
key = "${p.name}.${key}"
p = p.parent
}
map[key] = n.value[0]
}
}
return map
}

4 comments:

Anonymous said...

This just returns a blank map for me.

Anonymous said...

This no longer works.

I've updated it:

def Map xmlToMap(String xml) {
def root = new XmlParser().parseText(xml)
def map = [:]
root.depthFirst().each { n ->
if(n.children().size() == 1) {
def key = n.name()
def p = n.parent()
while(p?.parent() != null) {
key = "${p.name()}.${key}"
p = p.parent()
}
map[key] = "${n.value()[0]}"
}
}
return map
}

chanwit said...

Thanks you for the update.

Anonymous said...

Handling xml with lists; maybe this?
def root = new XmlParser().parse(xml)
def map = [:]
root.depthFirst().each { n ->
if(n.children().size() == 1) {
def key = n.name()
def p = n.parent()
while(p?.parent() != null) {
key = "${p.name()}.${key}"
p = p.parent()
}
if(map[key]) {
t = map[key]
if(t instanceof List)
map[key] = t + "${n.value()[0]}"
else
map[key] = [t,"${n.value()[0]}"]
}
else {
map[key] = "${n.value()[0]}"
}
}
}
return map