Técnico

Groovy XmlSlurper & invokeMethod

Grande parte do dinamismo do groovy se deve ao invokeMethod. Quando declarado, este método será executado caso um método inexistente for chamado no objeto em questão (Method missing no Ruby ou Python).

“invokeMethod(String name, Object args) is at the heart of Groovy metaprogramming.”, Groovy Recipes

Vamos ao exemplo:


class Sample {
Object invokeMethod( String name, Object params ) {
println "method ${name} with params ${params}"
}
}

Podemos agora chamar qualquer método em um objeto Sample:

def sample = new Sample()
sample.anything "arg1", "arg2"

E devido ao “method missing” do groovy, podemos navegar em um XML de forma elegante usando o XmlSlurper (navegação semelhante ao E4X):


def xml = """


Bruno
bruno.fuster@redspark.io


Fuster
bruno.fuster@redspark.io


"""

def users = new XmlSlurper().parseText(xml)

//para cada user no xml
users.user.each { user ->
println user.@id
println user.name
}

No código acima estamos acessando os elementos do XML através de um método ou atributo inexistente (users.user, user.name, user.@id), o que seria impossível sem invokeMethod e getProperty usado pelo XmlSlurper em conjunto com GPath.

Também poderiamos utilizar bibliotecas Java (XStream, JDOM, etc) para serializar objetos para XML e vice-versa, mas vamos brincar com groovy agora para obter uma lista de objetos do xml acima:


def objects = users.user.collect { xmlUser ->
new User(id: xmlUser.@id, name: xmlUser.name, email: xmlUser.email)
}

E serializar objetos para XML/JSON fica fácil com grails.converters e content negotiation:


import grails.converters.*
...
def list = {
withFormat {
xml(contentType:"text/xml") {
render User.list() as XML
}
json(contentType:"text/json") {
render User.list() as JSON
}
}
}
...

Produtivo, não ?

1 Comments

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Compartilhe isso: