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

18 de May de 2009 | By | 3 Comments

No post Manipulando arquivos XML em Java com a API DOM – Parte II vimos como fazer a leitura de um arquivo XML utilizando a API DOM presente no java (a partir versão 1.4). Neste post (último sobre a API DOM) vamos ver como editar um arquivo XML após tê-lo na árvore DOM.

Às vezes precisamos editar alguma informação do XML, modificar alguma informação, ou adicionar, ou até mesmo excluir algum dado do XML.

Vamos utilizar o XML abaixo como exemplo de arquivo inicial. O arquivo está nomeado como “contatos.xml”:

contatos_xml

Antes de começarmos a modificar o XML, temos que ter o arquivo na árvore DOM, para isso, vamos carregar o arquivo na memória:

//fazer o parse do arquivo e criar o documento XML
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse("contato.xml");

Após carregar o arquivo, vamos chegar no nó que desejamos modificar. Vamos aproveitar e imprimir as informações no console para verificação:

//Passo 1: obter o elemento raiz
Element raiz = doc.getDocumentElement();

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

//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);

Se um contato já estiver gravado (atributo gravado=”SIM”), então vamos removê-lo do arquivo. Para isso, utilizamos o método removeChild(Node noASerRemovido). Se o contato ainda não estiver gravado, vamos modificar o atributo para “SIM”:

//remove o elemento do XML se contato já está gravado
//caso contrário, marca como gravado
if (contato.isGravado()){
raiz.removeChild(elementoContato);
i--; //atualiza, já que alterou o lenght
} else{
elementoContato.setAttribute("gravado", "SIM");
}

Vamos agora substituir o telefone do contato de id=”03″. Para isso, vamos criar um novo Elemento telefone (lembrando que também temos que cria um Nó de texto para relacionar ao elemento Telefone (pode relembrar como é árvore DOM aqui)). Após criar o novo elemento telefone, vamos subtituir o novo elmento pelo elemento que já existe; para isso, utilizamos o método replaceChild(Node novoNo, Node antigoNo):

//subtitui o telefone do Pedro da Silva
if (contato.getId() == 3){
Element tel = doc.createElement("telefone");
tel.appendChild(doc.createTextNode("11 99999999"));
Node telefone = elementoContato.getElementsByTagName("telefone").item(0);
elementoContato.replaceChild(tel, telefone);
}

Vamos agora adicionar um novo elemento contato ao elmento raiz agenda. Para isso, vamos seguir a lógica da criação do elemento telefone. Passos a seguir:

  1. Criação do elemento contato
  2. Setar os atributos do elmento contato
  3. Criar o elemento nome + criar o TextNode (valor) do elemento nome
  4. Criar o elemento endereco + criar o TextNode (valor) do elemento endereco
  5. Criar o elemento telefone + criar o TextNode (valor) do elemento telefone
  6. Criar o elemento email + criar o TextNode (valor) do elemento email
  7. Adicionar o elementos nome, endereco, telefone e email ao elemento contato

Lembrar que a ordem em que os elementos são inseridos é muito importate!
Para facilitar e poder reusar o código futuramente, vamos criar um método que faça isso:

public Element criaElementoAPartirContato(Contato contato){
//cria um elemento contato
Element element = doc.createElement("contato");

//cria o atributo id e gravado
element.setAttribute("id", "04");
element.setAttribute("gravado", "SIM");

//cria os elementos
Element nome = criaElementoGenerico("nome", contato.getNome());
Element endereco = criaElementoGenerico("endereco", contato.getEndereco());
Element telefone = criaElementoGenerico("telefone", contato.getTelefone());
Element email = criaElementoGenerico("email", contato.getEmail());

//adiciona os elementos ao contato
element.appendChild(nome);
element.appendChild(endereco);
element.appendChild(telefone);
element.appendChild(email);

return element;
}

Vamos utilizar o método no código principal, adicionando o elmento criado ao elemento raiz:

//Cria um novo elemento
Element novoContato = criaElementoAPartirContato(criaContatoFicticio());
//adiciona um novo elemento no XML
raiz.appendChild(novoContato);

Bem, já vimos como remover, modificar e adicionar elementos ao XML. Agora falta apenas gravar o arquivo modificado em algum lugar!
Se desejar, pode criar uma classe para montar o XML na mão, ou seja, montar as tags, identação, etc. Mas tem que tomar muito cuidado quando for fazer isso, pois pode acabar modificando a estrutura na serialização (sem querer), e o XML pode ficar inválido.

Uma maneira que muitos desenvolvedores utilizam é criar uma transformação identidade, ou seja, é uma transformação XSL sem folha de estilo.
Você cria uma origem (documento DOM) e um destino (arquivo XML), e aplica a transformação sem folha de estilo.

//grava o documento XML editado
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new FileOutputStream("contato_modificado.xml"));
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(source, result);

Após rodar o programa, vamos ter o seguinte XML modificado:

contatos_mod_xml

O código completo desse post você pode fazer o download aqui (projeto no formato da IDE Eclipse)
download

Até a próxima!

Posts Similares

Filed in: Java, XML | Tags: , , , ,

Comments (3)

  1. Alexandre

    Olá, bem legal esse seu post, estou desenvolvendo um applet que deve ler um arquivo xml da própria máquina em que esta hospedado, mas não consigo obter o valor que esta no nó e estou fazendo algo parecido com o que você faz na segunda parte do código, mas quando tento fazer o mesmo cast que você faz, ele compila certo mas não carrega o conteúdo do nó para uma váriavel que recebe o conteúdo do nó como string, que coloquei apenas pra verificação. Se puder me ajudar fico grato.

  2. Arthur Gomes

    Como faço para adicionar novos dados no arquivo XML? O seu código apenas altera não é mesmo?
    Pode me ajudar?

  3. Olá Arthur,
    Você pode usar a mesma lógica para adicionar novos dados.
    []‘s

Leave a Reply

Trackback URL | RSS Feed for This Entry