Featured Posts

ExtJS, Spring MVC 3 e Hibernate 3.5: Exemplo de um... Este tutorial demonstra como implementar um CRUD Grid (Create, Read, Update, Delete) usando ExtJS, Spring MVC 3 e Hibernate 3.5 O que geralmente queremos fazer com os dados Create (Criar) - (Insert) Read...

Readmore

ExtJS plugin: PagingToolbarResizer Ei pessoal, Este é o meu primeiro plugin em ExtJS. Apesar de não ser algo complicado, estou muito feliz e é um grande feito para mim! Bem, chega e introduções e vamos ao que realmente interessa. O...

Readmore

8++ perguntas para @loiane - por @hlegius Tempos atrás o Helio me enviou um questionário para eu responder, uma espécie de "entrevista". E agora ele publicou no blog dele! :) São minhas opiniões pessoais, e isso não quer dizer que estou...

Readmore

Carreira em TI: Currículo em Inglês Uma das grandes dificuldades para as pessoas da área de TI é, muitas vezes, escrever um bom currículo em inglês. E ter um currículo em inglês, é essencial, já que inglês é tão importante quanto...

Readmore

Entrevista para o Jornal A Tribuna Jan/2010: Profissões... Na última de semana de janeiro tive a honra de conceder mais uma entrevista para o jornal A Tribuna - vendido no Espírito Santo, meu estado natal - sobre mercado de trabalho na área de TI. A reportagem...

Readmore

Manipulando arquivos XML em Java com a API DOM – Parte II

Posted by Loiane | Posted in XML, java | Posted on 07-05-2009

5

No post anterior, você viu como funcionar a API DOM do Java.

Neste post você irá aprender como ler um documento XML utilizando a interface DOM.
Para isso, você irá precisar:

  • JDK 1.4 ou superior
  • Editor de texto ou uma IDE Java de sua escolha

Para este post, vamos utilizar este XML como exemplo:

dom05

Para trabalhar com a informação de um arquivo XML, é ncessário primeiro fazer o parse para criar um objeto Document. Como o objeto Document é uma interface, não podemos instanciar diretamente. Geralmente, utilizamos uma Factory. O processo exato pode variar de implementação para implementação, mas as idéias são as mesmas.

A figura abaixo exemplifica o processo de parsear um XML com a API DOM (fonte: SUN):

javatechandxml_illus4

Os três passos em um ambiente java são:

  1. – Criar um DocumentBuilderFactory: este objeto cria um DocumentBuilder
  2. Criar um DocumentBuilder: este objeto faz o parse para criar um objeto do tipo Document
  3. Parsear o arquivo para criar um objeto Document.
//fazer o parse do arquivo e criar o documento XML
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(arquivoXML);

Uma vez que o é feito o parse do documento e o objeto Document é criado, a aplicação pode explorar a estrutura da árvore XML, exibindo a informação na tela, guardando os dados em um objeto, etc.
Todo documento XML inicia-se pelo elemento raiz. Um documento XML bem formado possui apenas um elemento raiz, também conhecido como DocumentElement. Então, o primeiro passo é a nossa aplicação obter esse elemento.

//Passo 1: obter o elemento raiz
Element raiz = doc.getDocumentElement();
System.out.println("O elemento raiz é: " + raiz.getNodeName());

Após a determinação do element raiz, podemos obter a lista de elementos filhos. O DOM fornece um tipo especial de interface de coleção chamada NodeList usada para referenciar uma lista de referências do tipo Node. Ou seja, sempre que desejarmos obter os filhos de um elemento, devemos utilizar esse método, mesmo sabendo que este determinado elemento possui apenas 1 subelemento.

Vamos obter agora os elementos do tipo contato:

//Passo 2: localizar os elementos filhos da agenda
NodeList listaContatos = raiz.getElementsByTagName("contato");

Como temos uma coleção de elementos contato, vamos percorrer cada um deles para obter as informações que queremos:

//Passo 3: obter os elementos de cada elemento contato
for (int i=0; i<listaContatos.getLength(); i++){

//como cada elemento do NodeList é um nó, precisamos fazer o cast
Element contato = (Element) listaContatos.item(i);

Agora que já temos acesso ao elemento contato, vamos começar a extrair as informações. Nosso primeiro passo é obter o valor do atributo id:

//Passo 4: obter o atributo id do contato
Attr id = contato.getAttributeNode("id");
System.out.println("Contato id: " + id.getNodeValue());

Após obtermos o atributo, vamos começar a extrair as informações dos elementos do contato. Para isso, vamos obter um NodeList com os elementos do tipo ‘nome’. Como sabemos que o arquivo XML tem apenas um elemento do tipo nome para cada elemento do tipo contato, podemos fazer referência diretamente para o primeiro elemento dessa lista. Como visto no post passado, um nó do tipo elemento possui valor null, então não podemos pegar diretamente o valor desse nó, temos que pegar o valor do nó texto, que obtemos através do método getFirstChild():

//Passo 5: obtém o nome do contato
NodeList listaNomes = contato.getElementsByTagName("nome");
Node nome = listaNomes.item(0).getFirstChild();
System.out.println("Nome: " + nome.getNodeValue());

Fazemos isso para cada informação que desejamos extrair: endereco, telefone e email. Apenas precisamos modificar a String passada como argumento pelo método getElementsByTagName. Fica assim:

//Passo 6: obtém o endereço do contato
NodeList listaEndereco = contato.getElementsByTagName("endereco");
Node endereco = listaEndereco.item(0).getFirstChild();
System.out.println("Endereço: " + endereco.getNodeValue());

//Passo 7: obtém o telefone do contato
NodeList listaTelefone = contato.getElementsByTagName("telefone");
Node telefone = listaTelefone.item(0).getFirstChild();
System.out.println("Telefone: " + telefone.getNodeValue());

//Passo 8: obtém o email do contato
NodeList listaEmail = contato.getElementsByTagName("email");
Node email = listaEmail.item(0).getFirstChild();
System.out.println("Email: " + email.getNodeValue());

E acabamos de extrair todas as informações do XML!

O código de parsing também precisa considerar a captura de erros de exceção para reportar os vários erros que podem acontecer, como por exemplo:

  • ParserConfigurationException – acionado quando o DocumentBuilderFactory não consegue criar o parser.
  • SaxParseException – ocorrendo quando o parser encontra um problema na formatação do arquivo XML. O objeto Exception carrega informações sobre a localização do erro no arquivo.
  • IOException – Acionado quando um erro de arquivo ocorre.

Todo o código acima está dentro de um bloco try-catch:

} catch (ParserConfigurationException e) {
System.out.println("O parser não foi configurado corretamente.");
e.printStackTrace();
} catch (SAXException e) {
System.out.println("Problema ao fazer o parse do arquivo.");
e.printStackTrace();
} catch (IOException e) {
System.out.println("O arquivo não pode ser lido.");
e.printStackTrace();
}

Podemos melhorar o código na hora de obter as informações do contato, criando um método genérico para extrair o valor de uma tag específica:

public String obterValorElemento(Element elemento, String nomeElemento){
//obtém a lista de elementos
NodeList listaElemento = elemento.getElementsByTagName(nomeElemento);
if (listaElemento == null){
return null;
}
//obtém o elemento
Element noElemento = (Element) listaElemento.item(0);
if (noElemento == null){
return null;
}
//obtém o nó com a informação
Node no = noElemento.getFirstChild();
return no.getNodeValue();
}

Podemos melhorar mais ainda construindo um código que retorne uma lista de objetos do tipo Contato. Para isso, precisamos também contruir uma classe do tipo Contato:

public class Contato {

private int id;
private String nome;
private String endereco;
private String telefone;
private String email;

//métodos getters e setters
}

O método:

public Contato criaContato(Element elemento){
Contato contato = new Contato();
contato.setId(Integer.parseInt(elemento.getAttributeNode("id").getNodeValue()));
contato.setNome(obterValorElemento(elemento,"nome"));
contato.setEndereco(obterValorElemento(elemento,"endereco"));
contato.setTelefone(obterValorElemento(elemento,"telefone"));
contato.setEmail(obterValorElemento(elemento,"email"));
return contato;
}

E nosso novo código:

//Passo 3: obter os elementos de cada elemento contato
for (int i=0; i<listaContatos.getLength(); i++){

//como cada elemento do NodeList é um nó, precisamos fazer o cast
Element elementoContato = (Element) listaContatos.item(i);

//cria um objeto Contato com as informações do elemento contato
Contato contato = criaContato(elementoContato);
System.out.println(contato);
}

O código completo desse post você pode fazer o download aqui (projeto no formato da IDE Eclipse, compilado com Java 5):

download

Até a próxima!

No proximo post sobre esta série, um passo a passo de como modificar um XML utilizando a API DOM.

Até a próxima!

:)

  • Share/Bookmark