Primeiras aulas do curso Java e XML: integração, parsing e validação

Java e XML: integração, parsing e validação

Representando dados de forma eficiente - Conhecendo o formato XML

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.

Representando dados de forma eficiente - Acessando tags de um XML

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.

Representando dados de forma eficiente - Acessando mais de um produto

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.

Sobre o curso Java e XML: integração, parsing e validação

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:

Aprenda Java acessando integralmente esse e outros cursos, comece hoje!

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1112 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana