Bem vindos ao Curso de XML da Alura! Nesse curso, aprenderemos o que é são arquivos XML, para que eles servem, quando devemos utilizá-los e diversas formas de trabalharmos com eles em Java.
Para o nosso treinamento, vamos imaginar que temos dois sistemas. O primeiro deles é um sistema de e-commerce no qual o usuário escolhe e compra um produto, gerando uma venda. Feito isso, a nossa loja virtual precisa pagar impostos e emitir uma nota fiscal. Sendo assim, precisaremos também de um sistema de notas fiscais.
Entretanto, os dados de venda foram feitos no sistema de e-commerce. Assim, o sistema de notas precisará acessar o sistema de vendas para gerar as notas fiscais. Mas como dois sistemas conseguem conversar entre si? O primeiro requisito será fazermos com que ambos mandem e recebam mensagens utilizando o mesmo idima, ou, em outras palavras, o mesmo formato.
Estamos falando, nesse caso, do XML, um formato definido na década de 90 pelo W3C, um consórcio internacional que ajuda a regulamentar a Web. Para visualizarmos como esse formato funciona, criaremos no Eclipse um documento chamado vendas.xml
.
<?xml version="1.0" encoding="UTF-8"?>
Em documentos XML conseguimos organizar qualquer tipo de informação de forma hierárquica, o que é feito por meio de tags. Sendo assim, se quisermos representar uma venda, podemos literalmente criar uma tag <venda>
.
<?xml version="1.0" encoding="UTF-8"?>
<venda>
</venda>
Em um cenário bastante simples, quais dados são importantes para uma venda? Um atributo que certamente estará presente é a <formaDePagamento>
. Na tag referente a ele, podemos incluir um valor, como Cartão
.
<?xml version="1.0" encoding="UTF-8"?>
<venda>
<formaDePagamento>Cartão</formaDePagamento>
</venda>
Perceba que a <formadePagamento>
está dentro da tag <venda>
, organizando as informações em uma hierarquia. Outro dado importante em uma venda é o <produto>
. Mantendo nosso cenário simples, todo produto precisa ter um <nome>
e um <preco>
.
<?xml version="1.0" encoding="UTF-8"?>
<venda>
<formaDePagamento>Cartão</formaDePagamento>
<produto>
<nome>Livro de xml</nome>
<preco>29.90</preco>
</produto>
</venda>
Assim, criamos uma <venda>
que possui uma <formaDePagamento>
e um <produto>
. Este, por sua vez, possui um <nome>
e um <preco>
. Tudo isso foi construído de maneira hierárquica e bastante intuitiva. A seguir, aprenderemos a trabalhar com esse arquivo utilizando a linguagem Java.
Vamos começar a trabalhar com o arquivo XML utilizando o Java. Primeiro, criaremos um novo pacote br.com.alura.Teste
, e todo código que escrevermos e precisarmos testar será armazenado nele. Dentro do pacote, criaremos uma classe Sistema.java
.
package br.com.alura.Teste;
public class Sistema {
}
Se a classe Sistema
é o ponto inicial da nossa aplicação, precisará ter um método main()
. No Eclipse, podemos digitar apenas "main" e pressionar "Ctrl + Espaço" para autocompletar o método.
public class Sistema {
public static void main(String[] args) {
}
}
Para carregarmos o arquivo XML na memória, precisaremos de um document builder, ou seja, uma classe que constrói documentos. Podemos conseguir isso por meio de uma DocumentBuilderFactory
, que importaremos de javax.xml.parsers
e representaremos por uma fabrica
. Chamaremos então o método newInstance()
para obtermos uma referência desse tipo.
import javax.xml.parsers.DocumentBuilderFactory;
public class Sistema {
public static void main(String[] args) {
DocumentBuilderFactory fabrica = DocumentBuilderFactory.newInstance();
}
}
Da fabrica
, podemos pedir um novo construtor de documentos com newDocumentBuilder()
. Com "Ctrl + 1", podemos associar essa chamada a uma variável local que chamaremos de bulder
.
public class Sistema {
public static void main(String[] args) {
DocumentBuilderFactory fabrica = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fabrica.newDocumentBuilder();
}
}
Feito isso, pediremos para esse builder
parsear (parse()
) o nosso arquivo XML, passando como argumento o diretório dele.
public class Sistema {
public static void main(String[] args) {
DocumentBuilderFactory fabrica = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fabrica.newDocumentBuilder();
builder.parse("src/vendas.xml");
}
}
O Eclipse apontará alguns problemas pois os métodos newDocumentBuilder()
e parse()
lançam algumas exceções checadas, ou seja, que somos obrigados a tratar. Como não estamos nos preocupando com exceções no momento, usaremos a opção "Add throws declaration".
public class Sistema {
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory fabrica = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fabrica.newDocumentBuilder();
builder.parse("src/vendas.xml");
}
}
Por fim, tendo carregado o documetno na memória, vamos salvá-lo a uma variável `document´.
public class Sistema {
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory fabrica = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fabrica.newDocumentBuilder();
Document document = builder.parse("src/vendas.xml");
}
}
Já temos a referência para o nosso documento, e agora queremos, de alguma maneira, ler a formaDePagamento
e imprimir o valor na tela com System.out.println()
. Mas como acessaremos cada tag do nosso XML?
A partir de document
podemos acessar alguns métodos, e um deles é o getElementosByTagName()
. Se passarmos o nome da tag para esse método, ele procurará uma referência para cada elemento. Sendo assim, passaremos formaDePagamento
como parâmetro e salvaremos todas as referências encontradas em uma variável formasDePagamento
- no plural, já que o método getElementosByTagName()
nos traz uma lista com todas as tags com o nome passado para ele, ainda que no nosso documento tenhamos apenas uma.
Pensando nisso, chamaremos formasDePagamento.item(0)
para buscarmos somente a primeira referência dessa lista, associando-a a uma variável fdp
(abreviação de formaDePagamento
). Isso nos retornará um objeto do tipo Node
, que não possui os métodos que nos interessam. Portanto, faremos um casting para Element
, outra interface do Java que pode ser importada de org.w3c.dom
e que possui o método getTextContent()
para pegarmos o conteúdo de texto do XML.
public class Sistema {
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory fabrica = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fabrica.newDocumentBuilder();
Document document = builder.parse("src/vendas.xml");
NodeList formasDePagamento = document.getElementsByTagName("formaDePagamento");
Element fdp= (Element) formasDePagamento.item(0);
String formaDePagamento = fdp.getTextContent();
System.out.println(formaDePagamento);
}
}
Feita essa construção, executaremos nosso código clicando no botão de "Play". Como retorno, teremos:
Cartão
Se mudarmos o conteúdo da tag <formaDePagamento
em vendas.xml
para "Débito", salvarmos o arquivo e rodarmos o código novamente, teremos como retorno:
Débito
Já se quiséssemos pegar o nome do produto, ao invés de procurarmos pela tag formaDePagamento
em getElementsByTagName()
, procuraríamos pela tag nome
. Assim, nosso retorno seria:
Livro de xml
Ou seja, é bastante fácil acessar qualquer tag de um documento XML utilizando as classes que o próprio Java nos fornece. O Java possui diversas especificações, que são conjuntos de interfaces cujo objetivo é desempenhar alguma função. Para manipular XML, temos uma especificação chamada JAXP (Java API for XML Processing).
No próximo vídeo aprenderemos a trabalhar com mais de um produto na nossa venda.
Agora que aprendemos a pegar o conteúdo de uma tag do nosso XML, vamos incorporar mais informações a ele. Afinal, quando entramos em uma loja virtual é possível comprar quantos produtos quisermos. Pensando nisso, adicionaremos outro produto:
<?xml version="1.0" encoding="UTF-8"?>
<venda>
<formaDePagamento>Cartão</formaDePagamento>
<produto>
<nome>Livro de xml</nome>
<preco>29.90</preco>
</produto>
<produto>
<nome>Livro de O.O. java</nome>
<preco>29.90</preco>
</produto>
</venda>
Também poderíamos ter outros dados na nossa venda além de <formaDePagamento>
, como o <endereco>
de entrega. Note que, como essas tags estão no mesmo nível, poderíamos nos perder em relação à ordem - por exemplo, com um endereço intercalando os produtos.
<?xml version="1.0" encoding="UTF-8"?>
<venda>
<formaDePagamento>Cartão</formaDePagamento>
<produto>
<nome>Livro de xml</nome>
<preco>29.90</preco>
</produto>
<endereco></endereco>
<produto>
<nome>Livro de O.O. java</nome>
<preco>29.90</preco>
</produto>
</venda>
Essa construção está bastante desorganizada, não? Para facilitarmos a organização, agruparemos os produtos em uma única tag <produtos>
.
<?xml version="1.0" encoding="UTF-8"?>
<venda>
<formaDePagamento>Cartão</formaDePagamento>
<produtos>
<produto>
<nome>Livro de xml</nome>
<preco>29.90</preco>
</produto>
<produto>
<nome>Livro de O.O. java</nome>
<preco>29.90</preco>
</produto>
</produtos>
</venda>
Agora queremos exibir os nomes de todos os produtos. Começaremos renomeando nossas variáveis para adequá-las ao objeto que estamos buscando.
public class Sistema {
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory fabrica = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fabrica.newDocumentBuilder();
Document document = builder.parse("src/vendas.xml");
NodeList nomeProduto = document.getElementsByTagName("nome");
Element fdp= (Element) nomeProduto.item(0);
String nome = fdp.getTextContent();
System.out.println(nome);
}
}
Executando o código dessa forma, teremos como retorno somente o nome do primeiro produto, "Livro de xml". Se quiséssemos pegar o próximo produto, precisaríamos mudar o argumento do método item()
para 1
, obtendo o retorno "Livro de O.O. em java". Mas queremos todos os produtos recebidos no XML, não é? Pensando nisso, renomearemos a variável nomeProduto
para produtos
.
Se o retorno de getElementsByTagName()
é como uma lista, podemos percorrê-la utilizando um for
. Criaremos então um contador i
. Com ela, vamos iterar até o tamanho da lista produtos
com getLenght()
, incrementando cada iteração com i++
. Dentro da estrutura de repetição, colocaremos o código que pega o nome dos produtos, chamando de produto
o item atual. Feito isso, ao invés de passarmos um índice fixo para o método item()
, passaremos o nosso contador i
e, por fim, executaremos o código.
NodeList produtos = document.getElementsByTagName("nome");
for(int i = 0;i < produtos.getLength();i++) {
Element produto = (Element) produtos.item(i);
String nome = produto.getTextContent();
System.out.println(nome);
}
Teremos como retorno:
Livro de xml
Livro de O.O. java
Nosso código funcionou! Mas e se quiséssemos exibir o nome e o preço? Da maneira que nosso código está agora, teríamos que criar outra lista,e assim sucessivamente para cada atributo desejado. No XML, nós representamos um produto por tags, e no Java essa representação geralmente se dá por meio de uma classe. Pensando assim, ao invés de simplesmente pegarmos o valor de uma tag, criaremos uma instância de uma classe Produto
.
Em "src", pressionaremos "Ctrl + N" criaremos um novo pacote br.com.alura.Model
, onde armazenaremos os nossos modelos. Repetiremos o "Ctrl + N", desta vez para criarmos a classe Produto.java
. Feito isso, voltaremos a Sistema.java
e, dentro do laço de repetição, instanciaremos a classe Produto
, atribuindo-a a uma variável prod
. Essa instância receberá como argumentos o nome
e o preco
do produto. Sendo assim, criaremos também um double preco
que, por enquanto, receberá outra chamada de getTextContent()
.
for(int i = 0;i < produtos.getLength();i++) {
Element produto = (Element) produtos.item(i);
String nome = produto.getTextContent();
double preco = produto.getTextContent();
Produto prod = new Produto(nome, preco);
System.out.println(nome);
}
Com o auxílio do Eclipse, criaremos o construtor Produto()
que recebe os argumentos citados. Nele, faremos a atribuição dos respectivos valores com o this
, criaremos os atributos privados nome
e preco
e geraremos seus getters e setters
package br.com.alura.Model;
public class Produto {
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public double getPreco() {
return preco;
}
public void setPreco(double preco) {
this.preco = preco;
}
private String nome;
private double preco;
public Produto(String nome, double preco) {
this.nome = nome;
this.preco = preco;
}
}
No Sistema
, precisamos de uma maneira de realmente pegar o preco
, afinal produto.getTextContent()
também nos retornará ao nome. Para termos acesso a todas essas informações do produto, ao invés de pegarmos a tag nome
em getElementsByTagName()
, pegaremos produto
. Feito isso, podemos chamar produto.getElementsByTagName("nome").item(0).getTextContent()
para conseguirmos o nome, e produto.getElementsByTagName("preco").item(0).getTextContent()
para o preço. Este último nos retornará um erro, já que estamos tentando associar uma string a um double. Para resolvermos esse problema, chamaremos Double.parseDouble()
. Por fim, exibiremos o prod
na tela com o System.out.println()
.
NodeList produtos = document.getElementsByTagName("produto");
for(int i = 0;i < produtos.getLength();i++) {
Element produto = (Element) produtos.item(i);
String nome = produto.getElementsByTagName("nome").item(0).getTextContent();
double preco = Double.parseDouble(produto.getElementsByTagName("preco").item(0).getTextContent());
Produto prod = new Produto(nome, preco);
System.out.println(prod);
Como retorno, teremos:
br.com.alura.Model.Produto@4590c9c3
br.com.alura.Model.Produto@5afa04c
Ou seja, recebemos o endereço de memória. Isso porque, para exibirmos os valores no System.out.println()
, precisaremos criar um método toString()
na classe Produto
. Sendo assim, faremos um @Override
e sobrescreveremos o método toString()
definido pela classe Object
. No caso, retornaremos o nome do produto e o preço.
@Override
public String toString() {
return "Nome:"+ nome + "\nPreço:"+preco+"\n";
}
Rodando nosso código novamente, teremos:
Nome:Livro de xml
Preço:29.9
Nome:Livro de O.O. java
Preço:29.9
Assim, conseguimos trabalhar com vários produtos recebidos em um XML de maneira relativamente fácil. No próximo vídeo trabalharemos com outras situações desse tipo.
O curso Java e XML: integração, parsing e validação possui 135 minutos de vídeos, em um total de 53 atividades. Gostou? Conheça nossos outros cursos de Java em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.
Certificado de que assistiu o curso e finalizou as atividades
Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets
Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado
Cursos de introdução a tecnologia através de games, apps e ciência
Reforço online de inglês e espanhol para aprimorar seu conhecimento
Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.
Certificado de que assistiu o curso e finalizou as atividades
Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets
Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado
Cursos de introdução a tecnologia através de games, apps e ciência
Reforço online de inglês e espanhol para aprimorar seu conhecimento
Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.
Certificado de que assistiu o curso e finalizou as atividades
Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets
Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado
Cursos de introdução a tecnologia através de games, apps e ciência
Reforço online de inglês e espanhol para aprimorar seu conhecimento
Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.
Certificado de que assistiu o curso e finalizou as atividades
Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets
Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado
Cursos de introdução a tecnologia através de games, apps e ciência
Reforço online de inglês e espanhol para aprimorar seu conhecimento
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos todas as semanas