Manipulando Arquivo XML Parte III: XStream

Neste tutorial vou exemplificar como manipular arquivos XML com as API XStream do Java. Veremos como criar um arquivo XML e como ler este arquivo. Esta biblioteca é externa e pode ser baixada em http://xstream.codehaus.org/download.html, neste tutorial foi utilizada a versão XStream-1.3.1.

1. Salvar arquivo

Antes de tudo, precisamos após criar o objeto XML salvá-lo em um arquivo. Vamos então criar um método para isso. Crie uma classe MainTest e em seguida crie o método salvarArquivo(String documento, String file). Já irei informar neste primeiro passo todos os imports necessários.

Listagem 1. Classe MainTest, Imports e Método SalvarArquivo
public class MainTest {

	private static void salvarArquivo(String documento, String file) {
		File path = new File("C:\\TutorialArquivos\\" + file);
		try {
			PrintWriter writer = new PrintWriter(path);
			writer.println(
			""
			);           
			writer.println(documento);
			writer.flush();
			writer.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}		
}

2. Estrutura do XML

Vamos utilizar três classes para manipular os dados que serão inseridos no XML. Nosso arquivo ficara com a estrutura do XML da figura 1.

XML

Figura 1 – XML


Crie a classe Telefone, Endereco e Contato conforme a listagem 2 do tutorial Parte I. Como devem ter visto na Figura 1, teremos mais de um telefone no arquivo, então é por este motivo que foi criada uma coleção de telefones na classe Contato. Enquanto isso, terá apenas um endereço no arquivo, por este motivo teremos um objeto Endereco na classe Contato.

3. Método gerarXML

Vamos gerar nosso XML a partir das classes da biblioteca XStream. Todos os passos estão descritos nos comentários inseridos no código fonte. O primeiro método mostra a forma mais simples de gerar o XML, porém trás um problema na nomeação das tags.

Listagem 2. Método gerarXML001
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public static void gerarXml001(Contato contato) {
	//Criamos o objeto que vai fazer o trabalho de gerar o xml
	XStream xStream = new XStream(new DomDriver());
	//O metodo toXML() transforma nosso objeto
	//contato em um padrao de saida no formato XML.
	String documento = xStream.toXML(contato);
	//A chamada ao metodo salvaArquivo passando por parametro
	//a String com o XML gerado e o nome do arquivo     
	salvarArquivo(documento, "gerarXml001.xml");
}

Após a execução do método da listagem 2, teremos um arquivo gerado conforme a listagem 3. Veja que as tags e  possuem o nome dos pacotes que as contém, mais o nome da classe referente. Já as tags  e  não possuem essa particularidade por serem atributos da classe Contato, o atributo telefones é uma coleção composta por objetos do tipo Telefone, por isso, as tags filhas de possuem a descrição do pacote e da classe a qual pertencem.

Listagem 3. Arquivo gerarXml001.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<br.mb.tutorialArquivos.xml.Contato>
  <id>100</id>
  <nome>Fulano da Silva</nome>
  <email>fulano@email.com</email>
  <endereco>
    <id>11</id>
    <logradouro>Rua dos Javanezes</logradouro>
    <bairro>Largo Zero</bairro>
    <cep>97010600</cep>
    <cidade>Java City</cidade>
    <complemento>Ap.103A</complemento>
    <numero>65</numero>
  </endereco>
  <telefones>
    <br.mb.tutorialArquivos.xml.Telefone>
      <id>1</id>
      <ddd>55</ddd>
      <numero>32214512</numero>
    </br.mb.tutorialArquivos.xml.Telefone>
    <br.mb.tutorialArquivos.xml.Telefone>
      <id>2</id>
      <ddd>55</ddd>
      <numero>99879885</numero>
    </br.mb.tutorialArquivos.xml.Telefone>
  </telefones>
</br.mb.tutorialArquivos.xml.Contato>

No método seguinte, mostrarei como alterar o nome das tags para ser possível utilizar qualquer nome desejado.

Listagem 4. Método gerarXML002
private static void gerarXml002(Contato contato) {
	//Criamos o objeto xStrem
	XStream xStream = new XStream(new DomDriver());
	//Vamos renomear nossa tag root para Contato
	//O 1° parametro indica o novo nome da Tag e
	//o 2° parametro indica a classe desta tag
	xStream.alias("Contato", Contato.class);
	//Varemos o mesmo com a tag Endereco.
	//Porém utilizando desta vez o método aliasField().
	//O 1° parametro recebe o nome que queremos dar a tag.
	//O 2° parametro indicamos a qual classe essa tag pertence
	//o 3° parametro indicamos o nome do atributo endereco na classe Contato,
	//no caso estamos referenciando o atributo endereco criado dentro da
	//classe Contato.
	xStream.aliasField("Endereco", Contato.class, "endereco");
	//Fazemos o mesmo processo para o atributo telefones
	xStream.aliasField("Telefones", Contato.class, "telefones");
	//Como telefones é uma lista temos
	// a tag pai  e as filhas .
	//Precisamos renomear também as tag filhas, para isso,
	//usamos o metodo alias() indicando a classe Telefone
	xStream.alias("Telefone", Telefone.class);

	String documento = xStream.toXML(contato);
	salvarArquivo(xStream.toXML(contato), "gerarXml002.xml");
}

Agora veja na listagem 5 o resultado após a execução do método gerarXml002().

Listagem 5. Arquivo gerarXml002.xml
<?xml version="1.0" encoding="ISO-8859-1">
<Contato>
  <id>100</id>
  <nome>Fulano da Silva</nome>
  <email>fulano@email.com</email>
  <Endereco>
    <id>11</id>
    <logradouro>Rua dos Javanezes</logradouro>
    <bairro>Largo Zero</bairro>
    <cep>97010600</cep>
    <cidade>Java City</cidade>
    <complemento>Ap.103A</complemento>
    <numero>65</numero>
  </Endereco>
  <Telefones>
    <Telefone>
      <id>1</id>
      <ddd>55</ddd>
      <numero>32214512</numero>
    </Telefone>
    <Telefone>
      <id>2</id>
      <ddd>55</ddd>
      <numero>99879885</numero>
    </Telefone>
  </Telefones>
</Contato>

Na listagem 6 temos o método que irá ler o conteúdo dos arquivos gerados, nesse exemplo estou lendo o arquivo gerarXml002.xml.

Listagem 6. Método lerXml
private static void lerXml() {
	FileReader reader = null;
	try {
		//carrega o arquivo XML para um objeto reader
		reader = new FileReader("C:\\TutorialArquivos\\gerarXml002.xml");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}
	//Cria o objeto xstream
	XStream xStream = new XStream(new DomDriver());
	//informamos as tags que serao lidas
	//como foi feito no metodo gerarXml002
	xStream.alias("Contato", Contato.class);
	xStream.aliasField("Endereco", Contato.class, "endereco");
	xStream.aliasField("Telefones", Contato.class, "telefones");
	xStream.alias("Telefone", Telefone.class);
	//cria um objeto Contato,
	//contendo os dados do xml
	Contato contato = (Contato) xStream.fromXML(reader);
	//Exibimos no console o resultado
	System.out.println(contato.toString());
}

4. Método main

No método main() iremos criar os objetos Contato, Endereco e Telefone e adicionar a eles os valores necessários.

Listagem 7. Método main
public static void main(String[] args) {
	Telefone residencial = new Telefone();
	residencial.setId(1);
	residencial.setDdd(55);
	residencial.setNumero(32214512);

	Telefone celular = new Telefone();
	celular.setId(2);
	celular.setDdd(55);
	celular.setNumero(99879885);

	Collection telefones = new ArrayList();
	telefones.add(residencial);
	telefones.add(celular);

	Endereco endereco = new Endereco();
	endereco.setId(11);
	endereco.setLogradouro("Rua dos Javanezes");
	endereco.setBairro("Largo Zero");
	endereco.setCep("97010600");
	endereco.setCidade("Java City");
	endereco.setNumero(65);
	endereco.setComplemento("Ap.103A");

	Contato contato = new Contato();
	contato.setId(100);
	contato.setNome("Fulano da Silva");
	contato.setEmail("fulano@email.com");
	contato.setEndereco(endereco);
	contato.setTelefones(telefones);

	gerarXML001(contato);
	gerarXML002(contato);
	lerXML();
}

Agora que criamos este método vamos executá-lo para gerar o arquivo XML e em seguida ler o conteúdo do arquivo gerado.

5. Gerando o XML através de anotações

Outra função da biblioteca XStream é que podemos anotar as classes que queremos gerar os XML’s, o que facilita ainda mais o nosso trabalho.

Vamos adicionar a classe Contato, Endereco e Telefone as anotações conforme a listagem 8.

Listagem 8. Anotando as classes
import com.thoughtworks.xstream.annotations.XStreamAlias;

import java.util.ArrayList;
import java.util.Collection;

@XStreamAlias("Contato")
public class Contato {
    private int id;
    private String nome;
    private String email;

    @XStreamAlias("Telefones")
    private Collection telefones = new ArrayList();
    @XStreamAlias("Endereco")
    private Endereco endereco;

	//demais metodos get, set e toString()
}

//Coloque a anotação também nas classes Endereco e Telefone
@XStreamAlias("Telefone")
public class Telefone { ... }

@XStreamAlias("Endereco")
public class Endereco { ... }

Criaremos agora o método que utilizara as anotações para a criação do XML, veja na listagem 9.

Listagem 9. Método gerarXml003 e lerXmlAnnotation
public static void gerarXml003(Contato contato) {
	XStream xStream = new XStream();
	//Usamos o método que detecta as classes anotadas
	xStream.autodetectAnnotations(true);
	String documento = xStream.toXML(contato);
	salvarArquivo(xStream.toXML(contato), "gerarXml003.xml");
}

private static void lerXmlAnnotation() {
	FileReader reader = null;
	try {
		//carrega o arquivo XML para um objeto reader
		reader = new FileReader(
		"C:\\TutorialArquivos\\gerarXml003.xml"
		);
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}
	//Cria o objeto xstream
	XStream xStream = new XStream(new DomDriver());
	//Para ler vamos utilizar outro metodo o
	//processAnnotations() e como parametro passamos
	//a classe que possui as anotacoes
	xStream.processAnnotations(Contato.class);

	Contato contato = (Contato) xStream.fromXML(reader);
	System.out.println(contato.toString());
}

Conclusão

Neste tutorial podemos ver as facilidades de trabalhar com a biblioteca XStream. Vimos como gerar e ler arquivos XML com e sem o uso de anotações. Fica como sugestão um leitura adicional, na página oficial da biblioteca XStream, dos tutoriais lá adicionados. Leia também a documentação sempre que tiver dúvidas sobre o que um método pode fazer.

Saiba mais

Documentação das classes da biblioteca XStream

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...