Practically Groovy: Construindo, Analisando e Explorando o XML

Manipulação de XML sem Esforços

Aprenda como é fácil decompor e analisar o XML utilizando Groovy. Nesta parte do artigo Practically Groovy, o autor Scott Davis mostra que, independentemente de você estar criando XML com MarkupBuilder e StreamingMarkupBuilder ou analisando XML com XmlParser e XmlSlurper, o Groovy oferece um conjunto de ferramentas atraentes para você lidar com esse formato universal de dados.

Parece que o XML sempre existiu. Na realidade, o XML celebrou seu décimo aniversário em 2008 (consulte Recursos). Com a linguagem Java™ antedatando o XML em apenas alguns anos, alguém poderia dizer que para os desenvolvedores Java, o XML sempre existiu.

Sobre esta Série

Groovy é uma linguagem de programação moderna que é executada na plataforma Java. Ela oferece integração com o código Java existente, ao introduzir novos recursos surpreendentes, como encerramentos e metaprogramação. Simplificando, o Groovy é aquilo com que a linguagem Java se pareceria se tivesse sido gravada no século 21.

A chave para a incorporação de qualquer nova ferramenta ao seu kit de ferramentas de desenvolvimento é saber quando utilizá-la e quando deixá-la guardada. O Groovy pode ser extremamente poderoso, mas apenas quando aplicado de forma adequada aos cenários apropriados. Portanto, a série Practically Groovy explora os usos práticos do Groovy, ajudando você a aprender quando e como aplicá-los com sucesso.

O inventor da linguagem Java, Sun Microsystems, é um grande defensor do XML desde o começo. Afinal de contas, a promessa do XML de independência de plataforma se encaixa perfeitamente à mensagem "gravar uma vez, executar em qualquer lugar" da linguagem Java. Dadas as sensibilidades compartilhadas entre duas tecnologias, você poderia pensar que a linguagem Java e o XML poderiam se dar melhor do que realmente se dão. De fato, analisar e gerar XML na linguagem Java parece totalmente estranho e intrincado.

Felizmente, o Groovy introduz novas e boas maneiras de se criar e processar XML. Com a ajuda de alguns exemplos (todos disponíveis para download), este artigo mostra como o Groovy torna a construção e a análise do XML agradavelmente simples.

Comparando a Análise do XML Java e Groovy

No final de "Alcançando o Each", introduzi o documento XML simples mostrado na Listagem 1. (Incluí o atributo type dessa vez para deixar as coisas um pouco mais interessantes.)

Listagem 1. Um Documento XML Listando as Linguagens que Conheço
<langs type="current">
  <language>Java</language>
  <language>Groovy</language>
  <language>JavaScript</language>
</langs>

A análise deste documento XML trivial não é, decididamente, trivial na linguagem Java, como você pode ver na Listagem 2. Ela utiliza 30 linhas de código para analisar o arquivo XML de cinco linhas.

Listagem 2. Analisando um Arquivo XML em Java
import org.xml.sax.SAXException;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.IOException;

public class ParseXml {
  public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse("src/languages.xml");

      //imprima o atributo "type"
      Element langs = doc.getDocumentElement();
      System.out.println("type = " + langs.getAttribute("type"));

      //imprima os elementos "language"
      NodeList list = langs.getElementsByTagName("language");
      for(int i = 0 ; i < list.getLength();i++) {
        Element language = (Element) list.item(i);
        System.out.println(language.getTextContent());
      }
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    }catch(SAXException se) {
      se.printStackTrace();
    }catch(IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

Compare o código Java na Listagem 2 com o código Groovy correspondente na Listagem 3:

Listagem 3. Analisando um XML em Groovy
def langs = new XmlParser().parse("languages.xml")
println "type = ${langs.attribute("type")}"
langs.language.each{
  println it.text()
}

//saída:
type = current
Java
Groovy
JavaScript

A melhor parte do código Groovy não é que é significativamente menor do que o código Java equivalente — embora utilizar cinco linhas do Groovy para analisar cinco linhas do XML seja uma vitória clara. O que eu mais gosto no código Groovy é que ele é muito mais expressivo. Quando escrevo langs.language.each, parece que estou trabalhando diretamente com o XML. Na versão Java, você não pode mais ver o XML.


Variáveis String e XML

Os benefícios do trabalho com o XML no Groovy se tornam cada vez mais evidentes quando você armazena o XML em uma variável String e não em um arquivo. As aspas triplas do Groovy (comumente chamadas de HereDoc em outras linguagens) facilitam o armazenamento do XML internamente, conforme mostrado na Listagem 4. A única mudança do exemplo do Groovy na Listagem 3 é a inversão da chamada de método XmlParser de parse() (que trata Files, InputStreamss, Readers e URIs) para parseText().

Listagem 4. Armazenando XML Internamente no Groovy
def xml = """
<langs type="current">
  <language>Java</language>
  <language>Groovy</language>
  <language>JavaScript</language>
</langs>
"""

def langs = new XmlParser().parseText(xml)
println "type = ${langs.attribute("type")}"
langs.language.each{
  println it.text()
}

Observe que as aspas triplas tratam o documento XML multilinhas com facilidade. A variável xml é realmente um java.lang.String comum — e você pode incluir println xml.class para verificar isso sozinho. As aspas triplas também tratam as aspas internas de type="current" sem forçar você a escapá-las manualmente com um caractere barra invertida, como você faria no código Java.

Faça o contraste da elegância simples do código Groovy na Listagem 4 com o código Java correspondente na Listagem 5:

Listagem 5. Armazenando XML Internamente no Código Java
import org.xml.sax.SAXException;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;

public class ParseXmlFromString {
  public static void main(String[] args) {
    String xml = "<langs type=\"current\">\n" +
            "  <language>Java</language>\n" +
            "  <language>Groovy</language>\n" +
            "  <language>JavaScript</language>\n" +
            "</langs>";

    byte[] xmlBytes = xml.getBytes();
    InputStream is = new ByteArrayInputStream(xmlBytes);

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(is);

      //imprima o atributo "type"
      Element langs = doc.getDocumentElement();
      System.out.println("type = " + langs.getAttribute("type"));
      //imprima os elementos "language"
      NodeList list = langs.getElementsByTagName("language");
      for(int i = 0 ; i < list.getLength();i++) {
        Element language = (Element) list.item(i);
        System.out.println(language.getTextContent());
      }
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    }catch(SAXException se) {
      se.printStackTrace();
    }catch(IOException ioe) {
      ioe.printStackTrace();
    }
  } }

Observe que a variável xml é poluída com caracteres de escape para as aspas internas e novas linhas. O mais problemático, no entanto, é ter que converter String em uma array byte e, novamente, em ByteArrayInputStream, antes da análise. Estranhamente, DocumentBuilder não fornece uma maneira direta de se analisar uma simples String como XML.


Criando XML com MarkupBuilder

A maior vitória do Groovy sobre a linguagem Java é quando você quer criar um documento XML em código. A Listagem 6 mostra as 50 linhas do código Java necessárias para a criação do snippet XML de cinco linhas:

Listagem 6. Criando XML com Código Java
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

public class CreateXml {
  public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.newDocument();

      Element langs = doc.createElement("langs");
      langs.setAttribute("type", "current");
      doc.appendChild(langs);

      Element language1 = doc.createElement("language");
      Text text1 = doc.createTextNode("Java");
      language1.appendChild(text1);
      langs.appendChild(language1);

      Element language2 = doc.createElement("language");
      Text text2 = doc.createTextNode("Groovy");
      language2.appendChild(text2);
      langs.appendChild(language2);

      Element language3 = doc.createElement("language");
      Text text3 = doc.createTextNode("JavaScript");
      language3.appendChild(text3);
      langs.appendChild(language3);

      // Saída do XML
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer transformer = tf.newTransformer();
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
      StringWriter sw = new StringWriter();
      StreamResult sr = new StreamResult(sw);
      DOMSource source = new DOMSource(doc);
      transformer.transform(source, sr);
      String xmlString = sw.toString();
      System.out.println(xmlString);
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    } catch (TransformerConfigurationException e) {
      e.printStackTrace();
    } catch (TransformerException e) {
      e.printStackTrace();
    }
  }
}

Eu sei que alguns de vocês estão exclamando "Minha nossa!" agora. Várias bibliotecas de terceiros podem deixar esse código muito mais direto — JDOM e dom4j são duas das mais populares. Mas nenhuma das bibliotecas Java se aproxima da simplicidade do uso de um MarkupBuilder do GroovyMarkupBuilder, conforme demonstrado na Listagem 7:

Listagem 7. Criando XML com Groovy
def xml = new groovy.xml.MarkupBuilder()
xml.langs(type:"current"){
  language("Java")
  language("Groovy")
  language("JavaScript")
}

Observe que estamos de volta à proporção de quase 1:1 do código XML. O mais importante, posso ver o XML novamente. E claro, as tags xml foram substituídas por closures delimitadas por chaves, e os atributos utilizam dois pontos (notação HashMap do Groovy) no lugar dos sinais de igual, mas a estrutura básica é reconhecível no Groovy ou XML. É quase como um DSL para construção de XML, você não acha?

O Groovy está apto para realizar esta mágica de Builder por ser uma linguagem dinâmica. A linguagem Java, por outro lado, é estática: o compilador Java garante que todos os métodos existem antes de você poder chamá-los. (O código Java não compilará, muito menos executará, se você tentar chamar um método não-existente.) Mas o Builder do Groovy demonstra que o erro de uma linguagem é o recurso de outra. Se você verificar as documentações sobre API para MarkupBuilder, você não vai encontrar nenhum método langs(), método language() ou qualquer outro nome de elemento. Felizmente, o Groovy pode capturar essas chamadas para métodos que existem e fazer algo produtivo com elas. No caso de um MarkupBuilder, ele utiliza as chamadas de método fantasma e gera um XML bem formado.

A Listagem 8 expande o exemplo simples de MarkupBuilder que acabei de mostrar. Se você quiser capturar a saída XML em uma variável String, passe StringWriter para o construtor de MarkupBuilder. Se quiser incluir mais atributos para langs, simplesmente, passe-os separados por vírgulas. Observe que o corpo do elemento language é um valor sem um nome na frente. Você pode incluir atributos e um corpo na mesma lista delimitada por vírgulas.

Listagem 8. Um Exemplo de MarkupBuilder Expandido
def sw = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(sw)
xml.langs(type:"current", count:3, mainstream:true){
  language(flavor:"static", version:"1.5", "Java")
  language(flavor:"dynamic", version:"1.6.0", "Groovy")
  language(flavor:"dynamic", version:"1.9", "JavaScript")
}
println sw

//saída:
<langs type='current' count='3' mainstream='true'>
  <language flavor='static' version='1.5'>Java</language>
  <language flavor='dynamic' version='1.6.0'>Groovy</language>
  <language flavor='dynamic' version='1.9'>JavaScript</language>
</langs>

Com alguns desses truques do MarkupBuilder em seu currículo, você pode levar as coisas para direções interessantes. Por exemplo, é possível construir rapidamente um documento HTML bem formado e gravá-lo em um arquivo. A Listagem 9 mostra o código:

Listagem 9. Construindo HTML com um MarkupBuilder
def sw = new StringWriter()
def html = new groovy.xml.MarkupBuilder(sw)
html.html{
  head{
    title("Links")
  }
  body{
    h1("Here are my HTML bookmarks")
    table(border:1){
      tr{
        th("what")
        th("where")
      }
      tr{
        td("Groovy Articles")
        td{
          a(href:"http://ibm.com/developerworks", "DeveloperWorks")
        }
      }
    }
  }
}

def f = new File("index.html")
f.write(sw.toString())

//saída:
<html>
  <head>
    <title>Links</title>
  </head>
  <body>
    <h1>Here are my HTML bookmarks</h1>
    <table border='1'>
      <tr>
        <th>what</th>
        <th>where</th>
      </tr>
      <tr>
        <td>Groovy Articles</td>
        <td>
          <a href='http://ibm.com/developerworks'>DeveloperWorks</a>
        </td>
      </tr>
    </table>
  </body>
</html>

A Figura 1 mostra a visualização do navegador do HTML construído na Listagem 9:

Figura 1. O HTML Renderizado
O HTML Renderizado

Criando XML com StreamingMarkupBuilder

MarkupBuilder é excelente para a construção de documentos XML simples de forma síncrona. Para a criação de XML mais avançado, o Groovy oferece um StreamingMarkupBuilder. Com isso, você pode incluir todos os extras do XML, como instruções de processamento, espaços de nomes e texto sem escape (perfeito para blocos CDATA) utilizando o objeto auxiliar mkp. A Listagem 10 oferece a você um tour rápido pelos interessantes recursos do StreamingMarkupBuilder:

Listagem 10. Criando XML com StreamingMarkupBuilder
def comment = "<![CDATA[<!-- address is new to this release -->]]>"
def builder = new groovy.xml.StreamingMarkupBuilder()
builder.encoding = "UTF-8"
def person = {
  mkp.xmlDeclaration()
  mkp.pi("xml-stylesheet": "type='text/xsl' href='myfile.xslt'" )
  mkp.declareNamespace('':'http://myDefaultNamespace')
  mkp.declareNamespace('location':'http://someOtherNamespace')
  person(id:100){
    firstname("Jane")
    lastname("Doe")
    mkp.yieldUnescaped(comment)
    location.address("123 Main")
  }
}
def writer = new FileWriter("person.xml")
writer << builder.bind(person)

//saída:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='myfile.xslt'?>
<person id='100'
        xmlns='http://myDefaultNamespace'
        xmlns:location='http://someOtherNamespace'>
  <firstname>Jane</firstname>
  <lastname>Doe</lastname>
  <![CDATA[<!-- address is new to this release -->]]>
  <location:address>123 Main</location:address>
</person>

Observe que StreamingMarkupBuilder não produz o XML final até você chamar o método bind(), passando o encerramento que contém a marcação e todas as instruções. Isso permite construir várias partes do documento XML assincronamente e emiti-las todas de uma só vez. (Consulte Recursos para obter mais informações.)


Entendendo XmlParser

O Groovy oferece a você duas maneiras de produzir XML — MarkupBuilder e StreamingMarkupBuilder — cada uma com recursos diferentes. O mesmo é verdade com a análise XML. Você pode utilizar XmlParser ou XmlSlurper.

XmlParser oferece uma visão mais centrada em programador do documento XML. Se você se sentir confortável em pensar no documento em termos de Listas e Mapas (para Elementos e Atributos, respectivamente), você deverá se sentir confortável com XmlParser. A Listagem 11 analisa o XmlParser um pouco:

Listagem 11. Um Exame Mais Detalhado do XmlParser
def xml = """
<langs type='current' count='3' mainstream='true'>
  <language flavor='static' version='1.5'>Java</language>
  <language flavor='dynamic' version='1.6.0'>Groovy</language>
  <language flavor='dynamic' version='1.9'>JavaScript</language>
</langs>
"""

def langs = new XmlParser().parseText(xml)
println langs.getClass()
// classe groovy.util.Node

println langs
/*
langs[attributes={type=current, count=3, mainstream=true};
      value=[language[attributes={flavor=static, version=1.5};
                      value=[Java]],
             language[attributes={flavor=dynamic, version=1.6.0};
                      value=[Groovy]],
             language[attributes={flavor=dynamic, version=1.9};
                      value=[JavaScript]]
            ]
]
*/

Observe que o método XmlParser.parseText() retorna um groovy.util.Node — neste caso, a raiz Node do documento XML. Quando você chama println langs, ele chama o método Node.toString(), retornando a saída de depuração. Para chegar aos dados reais, você precisa chamar Node.attribute() ou Node.text().


Obtendo Atributos com XmlParser

Como você viu anteriormente, é possível obter um atributo individual chamando Node.attribute("key"). Se você chamar Node.attributes(), ele retorna HashMap que contém todos os atributos Node. Utilizando o encerramento each sobre o qual você aprendeu em "Alcançando o Each," examinar cada um dos atributos não é uma boa ideia. Consulte a Listagem 12 para ver um exemplo disso. (Consulte o Recursos para obter documentações de API sobre groovy.util.Node.)

Listagem 12. XmlParser Trata Atributos como um HashMap
def langs = new XmlParser().parseText(xml)

println langs.attribute("count")
// 3

langs.attributes().each{k,v->
  println "-" * 15
  println k
  println v
}

//saída:
---------------
type
current
---------------
count
3
---------------
mainstream
true

Como o trabalho com atributos é agradável, XmlParser oferece um suporte ainda mais engenhoso para você lidar com elementos.


Obtendo Elementos com XmlParser

XmlParser oferece uma maneira intuitiva de se consultar elementos chamados GPath. (Ele é semelhante ao XPath, implementado apenas no Groovy.) Por exemplo, a Listagem 13 demonstra que o constructo langs.language que utilizei anteriormente retorna groovy.util.NodeList contendo os resultados da consulta. Um NodeList estende java.util.ArrayList, portanto, basicamente, ele é uma Lista à qual foi concedida uma superpotência GPath.

Listagem 13. Consultando com GPath e XmlParser
def langs = new XmlParser().parseText(xml)
// sintaxe da consulta de atalho
// em um NodeList anônimo
langs.language.each{
  println it.text()
}

// separando a consulta
// e o encerramento each
// em partes distintas
def list = langs.language
list.each{
  println it.text()
}

println list.getClass()
// groovy.util.NodeList

GPath, é claro, é o complemento para MarkupBuilder. Ele utiliza o mesmo truque de chamar métodos fantasmas que não existem; apenas dessa vez, ele é utilizado para consultar XML existente em vez de gerá-lo on the fly.

Sabendo que o resultado de uma consulta GPath é uma Lista, você pode deixar seu código muito mais conciso. O Groovy oferece um operador spread-dot. Em uma única linha de código, essencialmente, ele faz a iteração através da lista e executa a chamada de método em cada item. Os resultados são retornados como uma Lista. Por exemplo, se sua maior preocupação for chamar o método Node.text() em cada item nos resultados da consulta, a Listagem 14 mostrará como fazer isso em uma única linha de código:

Listagem 14. Combinando o Operador spread-dot com GPath
// a maneira longa de se reunir os resultados
def results = []
langs.language.each{
  results << it.text()
}

// a maneira curta utilizando o operador spread-dot
def values = langs.language*.text()
// [Java, Groovy, JavaScript]

// reunindo rapidamente todos os atributos de versão
def versions = langs.language*.attribute("version")
// [1.5, 1.6.0, 1.9]

Sendo tão engenhoso e poderoso quanto o XmlParser é, XmlSlurper leva isso até o próximo nível.


Analisando XML com XmlSlurper

De volta à Listagem 2, eu disse que o Groovy me faz sentir como se eu estivesse trabalhando diretamente com o XML. XmlParser é totalmente capaz, mas ele ainda deixa você trabalhando com o XML programaticamente. Você é apresentado a Listas de s e HashMaps de Atributos, e ainda é forçado a chamar métodos como Node.attribute() e Node.text() para chegar aos dados principais. XmlSlurper remove os últimos vestígios de chamadas de método, deixando você com a doce ilusão de estar lidando com o XML diretamente.

Tecnicamente, XmlParser retorna s e NodeLists, enquanto que XmlSlurper retorna um groovy.util.slurpersupport.GPathResult. Mas agora que você já sabe, quero que você esqueça que mencionei os detalhes de implementação do XmlSlurper. Você vai gostar ainda mais do show de mágicas se não descobrir o truque espiando por trás das cortinas.

A Listagem 15 mostra um XmlParser e um XmlSlurper lado a lado:

Listagem 15. XmlParser e XmlSlurper
def xml = """
<langs type='current' count='3' mainstream='true'>
  <language flavor='static' version='1.5'>Java</language>
  <language flavor='dynamic' version='1.6.0'>Groovy</language>
  <language flavor='dynamic' version='1.9'>JavaScript</language>
</langs>
"""

def langs = new XmlParser().parseText(xml)
println langs.attribute("count")
langs.language.each{
  println it.text()
}

langs = new XmlSlurper().parseText(xml)
println langs.@count
langs.language.each{
  println it
}

Observe que XmlSlurper elimina qualquer indício de chamadas de método. Em vez de chamar langs.attribute("count"), você chama langs.@count. O sinal de arroba (@) é emprestado de XPath, mas o resultado é a ilusão de que você está trabalhando com o atributo diretamente, e não chamando o método attribute(). Em vez de chamar it.text(), você simplesmente chama it. A suposição é de que você queira trabalhar diretamente com o conteúdo do elemento.


XmlSlurper no Mundo Real

Avançando além de langs e language, aqui está um exemplo do mundo real do XmlSlurper em ação. Yahoo! oferece informações atuais sobre a previsão do tempo por CEP como um RSS feed. RSS, é claro, é um dialeto especializado do XML. Digite http://weather.yahooapis.com/forecastrss?p=80020 em um navegador da Web. Fique à vontade para trocar o CEP de Broomfield, Colorado sozinho. A Listagem 16 mostra uma versão simplificada do RSS feed resultante:

Listagem 16. Yahoo! RSS feed mostrando as condições do tempo atual
<rss version="2.0"
     xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
     xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
  <channel>
    <title>Yahoo! Weather - Broomfield, CO</title>
    <yweather:location city="Broomfield" region="CO"   country="US"/>
    <yweather:astronomy sunrise="6:36 am"   sunset="5:50 pm"/>

    <item>
      <title>Conditions for Broomfield, CO at 7:47 am MST</title>
      <pubDate>Fri, 27 Feb 2009 7:47 am MST</pubDate>
      <yweather:condition text="Partly Cloudy"
                          code="30"  temp="25"
                          date="Fri, 27 Feb 2009 7:47 am MST" />
    </item>
  </channel>
</rss>

A primeira coisa que você precisa fazer é botar as mãos nesse RSS programaticamente. Crie um arquivo chamado weather.groovy e inclua o código mostrado na Listagem 17:

Listagem 17. Obtendo o RSS Programaticamente
def baseUrl = "http://weather.yahooapis.com/forecastrss"

if(args){
  def zip = args[0]
  def url = baseUrl + "?p=" + zip
  def xml = url.toURL().text
  println xml
}else{
  println "USAGE: weather zipcode"
}

Digite groovy weather 80020 na linha de comando para verificar se você pode ver o RSS bruto.

A parte mais importante desse script é url.toURL().text. A A variável url é uma String bem-formada. Todas as Strings têm um método toURL() incluído pelo Groovy que os transforma em um java.net.URL. Todas as URLs, por sua vez, têm um método getText() incluído pelo Groovy que executa um pedido HTTP GET e retorna o resultado como uma String.

Agora que você armazenou o RSS na variável xml, misture um pouco de XmlSlurper para escolher a dedo as partes mais interessantes, como mostra a Listagem 18:

Listagem 18. Utilizando XmlSlurper para Analisar RSS
def baseUrl = "http://weather.yahooapis.com/forecastrss"
if(args){
  def zip = args[0]
  def url = baseUrl + "?p=" + zip
  def xml = url.toURL().text

  def rss = new XmlSlurper().parseText(xml)
  println rss.channel.title
  println "Sunrise: ${rss.channel.astronomy.@sunrise}"
  println "Sunset: ${rss.channel.astronomy.@sunset}"
  println "Currently:"
  println "\t" + rss.channel.item.condition.@date
  println "\t" + rss.channel.item.condition.@temp
  println "\t" + rss.channel.item.condition.@text
}else{
  println "USAGE: weather zipcode"
}

//saída:
Yahoo! Weather - Broomfield, CO
Sunrise: 6:36 am
Sunset: 5:50 pm
Currently:
   Fri, 27 Feb 2009 7:47 am MST
   25
   Partly Cloudy

Você viu como o XmlSlurper torna natural o trabalho com XML? Você imprime o elemento <title> referindo-se a ele diretamente — rss.channel.title. Você revela o atributo temp com um simples rss.channel.item.condition.@temp. Isso não parece programação. Parece um trabalho diretamente com o XML.

Você observou que o XmlSlurper até ignora os espaços de nomes? É possível ativar o reconhecimento de espaço de nomes no construtor, mas raramente faço isso. De um modo padrão, o XmlSlurper passa pelo XML como uma faca quente na manteiga.


Conclusão

Para ser um desenvolvedor de software bem-sucedido nos dias de hoje, você precisa de um conjunto de ferramentas que transformem o trabalho com XML em uma atividade que não exija nenhum esforço. O MarkupBuilder e o StreamingMarkupBuilder do Groovy facilitam muito a criação de um XML on the fly. XmlParser faz um grande trabalho ao dar a você Listas de Elementos e HashMaps de Atributos, e o XmlSlurper faz o código desaparecer completamente, deixando você com a doce ilusão de estar trabalhando com o XML diretamente.

Muito da força do processamento XML não seria possível sem os recursos dinâmicos do Groovy. No próximo artigo, vou explorar a natureza dinâmica do Groovy com você de maneira mais detalhada. Você vai aprender como metaprogramar trabalhos no Groovy, de métodos da moda incluídos em classes JDK padrão (como String.toURL() e List.each()) aos customizados que você vai incluir. Espero que até aqui, você possa encontrar bastante uso prático para o Groovy.


Download

DescriçãoNomeTamanho
Source code for this article's examplesj-pg05199.zip6KB

Recursos

Aprender

Obter produtos e tecnologias

  • Groovy: Faça o download do tarball ou arquivo zip mais recente do Groovy.

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre
ArticleID=396982
ArticleTitle=Practically Groovy: Construindo, Analisando e Explorando o XML
publish-date=05192009