Você está na página 1de 9

Processando XML com Java

Autor: Marcelo Akira Inuzuka


http://akira.sistemasabertos.com.br
akira@sintectus.com
Licena: Creative Commons - BY-SA - disponvel em
http://creativecommons.org/licenses/by-sa/2.5/br/deed.pt

1 - Por que usar XML com Java?

Revendo um pouco das utilizao de XML:


Troca de informaes entre empresas (B2B) - XML permite criar
arquivos de troca de informaes mais extensveis que
arquivos de dados de tamanho fixo ou delimitados por
caracteres (vrgula, tabulao, etc), assim bastante til
para troca de informaes (Comrcio Eletrnico, Hospitais,
etc). Alm de ser mais flexvel para alteraes, XML permite
ser validado.
Arquivos de configurao: cada vez mais utilizado XML para
definir configuraes de sistemas. Pode-se criar arquivos com
combinaes bem flexveis e sofisticados.
Web Services: uma implementao de servios que utilizam
protocolos baseados em XML, que permite interao entre clientes
e servidores remotos que interagem entre si, invocando mtodos e
trocando objetos. Clientes e servidores podem ser implementandos
em linguagens diferentes, por exemplo, Java e PHP.
RSS - agregao de notcias e outras informaes dinmicas
disponveis em pginas Web (preos, datas, etc);

Estas so apenas algumas das inmeras aplicaes possveis com XML.

2 - Suporte a XML no Java


Nas APIs dos JDK oficiais, se encontram dois pacotes que fornecem
funcionalidades para processar XML de forma 'genrica', ou seja,
facilitam a validao, leitura e escrita de arquivos XML, mas no
realizam utilizaes de mais alto nvel como RSS ou Web Services. Caso
voc queira realizar algum uso mais especfico, voc deve procurar
outros pacotes no-oficiais - aqueles que no so fornecidos pela JDK.
Existem trs pacotes principais que compem a JAXP (Java API for XML
Processing), que disponibilizado J2SE a partir do JDK1.5 e so aqui
apresentados:

org.w3c.dom (DOM) - permite modelar e manipular documentos XML,


especialmente XHTML. semelhante ao SAX. Carrega todo o
documento em memria.
org.xml.sax (SAX) - assim como DOM, tambm permite modelar e
manipular documentos XML, porm uma API que suporta eventos, ou
seja, voc pode disparar aes quando uma determinada estrutura
de tags ou valor encontrado. mais leve para rodar que o DOM,
uma vez que no carrega todo documento em memria.

javax.xml.transform (XSLT) - uma implementao que suporta


XSLT, que uma linguagem que permite realizar transformaes de
textos em formato XML para outros, por exemplo PDF, HTML, etc;

3 - Viso geral da API SAX


SAX uma API que voltada para processar arquivos XML como fluxos de
eventos; DOM por sua vez encara um arquivo XML como estrutura de
dados. Vejamos alguns tipos de eventos:

incio e final de documento;


incio e final de tags;

Assim, o programador pode realizar aes de acordo com os tipos de


eventos encontrados. Neste sentido, SAX mais adequado para realizar
operaes tais como:

Validao em documentos grandes: verificar se o XML vlido e


est de acordo com algum XML Schema (XSD) ou um DTD. Como o
processamento realizado tag a tag, no h necessidade de
carregar o documento inteiro - como DOM faz. Basta encontrar
alguma tag que infringe o padro para que o validador retorne uma
resposta de formato invlido.
Arquivos de configurao: SAX pode compilar configuraes
eficiente, carregando uma configurao de um sistema. Por
exemplo, Johnson demonstrou um exemplo de criao dinmica de
menus em uma interface grfica, baseado em um arquivo XML,
contendo a estrutura de menus e submenus http://www.javaworld.com/jw-03-2000/jw-03-xmlsax.html.

4 - Arquivo OlaMundo.xml
Suponha o seguinte arquivo xml mnimo:
<?xml version="1.0" encoding="UTF-8"?>
<recado>
<de>Akira</de>
<para>Todos</para>
<mensagem>Ola Mundo!</mensagem>
</recado>

Baixe o cdigo-fonte acima neste link:


http://wiki.sintectus.com/pub/GrupoJava/SlidesProcessandoXMLComJava/Ol
aMundo.xml
Com SAX podemos analisar este arquivo, detectar incio e final de
documento, bem como o incio e fim de cada um dos elementos: 'recado',
'de', 'para' e 'mensagem'.

5 - Vdeo: analisando OlaMundo.xml com SAX


Vejamos no
analisador
terminou o
execuo

vdeo seguinte os passo-a-passos necessrios para criar um


XML genrico, que simplesmente imprima quando iniciou e
documento e cada um dos elementos do XML. O resultado da
algo assim:

$ java testesxml.AnalisaXML1 OlaMundo.xml


Incio do documento
Incio do elemento: recado
Incio do elemento: de
Incio do elemento: de
Incio do elemento: para
Incio do elemento: para
Incio do elemento: mensagem
Incio do elemento: mensagem
Incio do elemento: recado
Final do documento

6 - Analisando OlaMundo.xml com SAX


Abaixo est o cdigo resultante. Observe os seguintes pontos:
1.o mtodo startDocument, endDocument, startElement e endElement
sobrepem os mtodos de mesmas assinaturas herdados de
DefaultHandler;
2.Voc pode inserir as aes nos corpos dos mtodos startDocument,
endDocument, startElement e endElement, de acordo com a
necessidade;
3.Para ler um arquivo XML, voc deve usar um XMLReader, que pode
ser obtido de XMLReaderFactory (fbrica de XMLReader) e que deve
ser associado a um ContentHandler e ErrorHandler. No nosso caso,
XMLReader associado ao prprio AnalisaXML, que uma subclasse
de DefaultHandler.
4.Para analisar um arquivo, necessrio analisar (parse) uma
instncia de InputSource, com o FileReader como argumento.
// baseado em http://www.saxproject.org/quickstart.html
package testesxml;
import
import
import
import
import
import

java.io.FileReader;
org.xml.sax.Attributes;
org.xml.sax.InputSource;
org.xml.sax.XMLReader;
org.xml.sax.helpers.DefaultHandler;
org.xml.sax.helpers.XMLReaderFactory;

public class AnalisaXML1 extends DefaultHandler {


//
//
//
//

os mtodos startDocument, endDocument,


startElement e endElement sobrepem os
mtodos de mesmas assinaturas
herdados de DefaultHandler:

public void startDocument() {


System.out.println("Incio do documento");
}

public void endDocument() {


System.out.println("Final do documento");
}
public void startElement(String ns, String nome,
String qNome, Attributes atributos) {
if (ns.equals(""))
System.out.println("Incio do elemento: " +
qNome);
else
System.out.println("Incio do elemento: {" + ns +
"}" + nome);
}
public void endElement(String ns, String nome, String qNome) {
if (ns.equals(""))
System.out.println("Incio do elemento: " +
qNome);
else
System.out.println("Final do Elemento: {" +
ns + "}" + nome);
}
public static void main(String[] args)
throws Exception {
// Para ler um arquivo XML, voc deve usar um XMLReader,
// que pode ser obtido de XMLReaderFactory
// (fbrica de XMLReader):
XMLReader xr = XMLReaderFactory.createXMLReader();
AnalisaXML1 analisador = new AnalisaXML1();
// O XMLReader deve estar associado
// a um analisador de XML:
xr.setContentHandler(analisador);
xr.setErrorHandler(analisador);
for (int i = 0; i < args.length; i++) {
// le os arquivos passados via linha de comando:
FileReader r = new FileReader(args[i]);
// Para analisar um arquivo, necessrio analisar
// (parse) uma instncia de InputSource,
// com o FileReader como argumento:
xr.parse(new InputSource(r));
}

Baixe o cdigo-fonte acima neste link:


http://wiki.sintectus.com/pub/GrupoJava/SlidesProcessandoXMLComJava/An
alisaXML1.java

7 - Mtodos callback
Alm de analisar cada tag, interessante tambm obter os dados - os
contedos - contidos em cada tag. Para isso, seria interessante
realizar uma consulta a API. Observe abaixo os mtodos callback - so
aqueles que recebem notificaes quando algum evento ocorre. No

exemplo anterior, utilizamos somente os mtodos callback


startDocument, endDocument, startElement e endElement. Verificando a
API, podemos notar que para obter os dados do arquivo XML, podemos
usar o mtodo characters.
Mtodo

Descrio

characters(char[] ch, int start, int


length)

Receive notification of
character data inside an
element.

void endDocument()

Receive notification of the


end of the document.

void endElement(String uri, String


localName, String qName)

Receive notification of the


end of an element.

void endPrefixMapping(String prefix)

Receive notification of the


end of a Namespace mapping.

void error(SAXParseException e)

Receive notification of a
recoverable parser error.

void ignorableWhitespace(char[] ch, int


start, int length)

Receive notification of
ignorable whitespace in
element content.

void notationDecl(String name, String


publicId, String systemId)

Receive notification of a
notation declaration.

void processingInstruction(String target, Receive notification of a


String data)
processing instruction.
void setDocumentLocator(Locator locator)

Receive a Locator object


for document events.

void skippedEntity(String name)

Receive notification of a
skipped entity.

void startDocument()

Receive notification of the


beginning of the document.

void startElement(String uri, String


localName, String qName, Attributes
attributes)

Receive notification of the


start of an element.

void startPrefixMapping(String prefix,


String uri)

Receive notification of the


start of a Namespace
mapping.

void unparsedEntityDecl(String name,


String publicId, String systemId, String
notationName)

Receive notification of an
unparsed entity
declaration.

void warning(SAXParseException e)

Receive notification of a
parser warning.

8 - Obtendo dados
Ento, para que possamos analisar os dados podemos inserir o seguinte
mtodo de callback:

...
public void characters (char ch[], int inicio, int comprimento)
{
System.out.print("Caracteres:
\"");
for (int i = start; i < inicio + comprimento; i++) {
switch (ch[i]) {
case '\\':
System.out.print("\\\\");
break;
case '"':
System.out.print("\\\"");
break;
case '\n':
System.out.print("\\n");
break;
case '\r':
System.out.print("\\r");
break;
case '\t':
System.out.print("\\t");
break;
default:
System.out.print(ch[i]);
break;
}
}
System.out.print("\"\n");
}
...

9 - Exemplo: Analisador de formulrios


Suponha que tenhamos o seguinte arquivo XML, que descreve um
formulrio grfico. Podemos utilizar XML para poder processar o
arquivo e gerar um formulrio dinmico.
<?xml version="1.0" encoding="UTF-8"?>
<form>
<rotulo x="100" y="100" valor="Nome:" />
<campotexto x="200" y="100" tamanho="100" valor="valor" />
</form>

Baixe o cdigo-fonte acima neste link:


http://wiki.sintectus.com/pub/GrupoJava/SlidesProcessandoXMLComJava/Fo
rmulario.xml
Este um possvel cdigo que analisa o XML acima e gera um formulrio
dinmicamente.
// baseado em http://www.saxproject.org/quickstart.html
package testesxml;
import
import
import
import
import
import
import
import
import

java.awt.TextField;
java.io.File;
java.io.FileReader;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JTextField;
org.xml.sax.Attributes;
org.xml.sax.InputSource;
org.xml.sax.XMLReader;

import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
public class AnalisaForm extends DefaultHandler {
// os mtodos startDocument, endDocument,
// startElement e endElement sobrepem os
// mtodos de mesmas assinaturas
// herdados de DefaultHandler:
JFrame form;
String componente;
public void startDocument() {
System.out.println("Incio do documento");
form = new JFrame();
form.setSize(500, 500);
form.setLayout(null);
}
public void endDocument() {
System.out.println("Final do documento");
form.setVisible(true);
}
public void startElement(String ns, String nome,
String qNome, Attributes atributos) {
if (ns.equals(""))
componente = qNome;
else
componente = nome;
System.out.println("componente="+componente);
if (componente.equals("rotulo")) {
JLabel l = new JLabel();
int x = Integer.parseInt(atributos.getValue("","x"));
int y = Integer.parseInt(atributos.getValue("", "y"));
String valor = atributos.getValue("", "valor");
l.setText(valor);
form.add(l);
l.setBounds(x,y,45,15);
} else if (componente.equals("campotexto")) {
JTextField t = new JTextField();
int x = Integer.parseInt(atributos.getValue("", "x"));
int y = Integer.parseInt(atributos.getValue("", "y"));
int tamanho = Integer.parseInt(atributos.getValue("",
"tamanho"));
String valor = atributos.getValue("", "valor");
t.setText(valor);
t.setSize(tamanho, 20);
form.add(t);
t.setLocation(x,y);
}
}
public void endElement(String ns, String nome, String qNome) {
}
public void characters(char ch[], int inicio, int comprimento) {
System.out.print("Caracteres:
\"");
for (int i = inicio; i < inicio + comprimento; i++) {
switch (ch[i]) {
case '\\':
System.out.print("\\\\");

break;
case '"':
System.out.print("\\\"");
break;
case '\n':
System.out.print("\\n");
break;
case '\r':
System.out.print("\\r");
break;
case '\t':
System.out.print("\\t");
break;
default:
System.out.print(ch[i]);
break;
}
}
System.out.print("\"\n");

public static void main(String[] args)


throws Exception {
// Para ler um arquivo XML, voc deve usar um XMLReader,
// que pode ser obtido de XMLReaderFactory
// (fbrica de XMLReader):
XMLReader xr = XMLReaderFactory.createXMLReader();
AnalisaForm analisador = new AnalisaForm();
// O XMLReader deve estar associado
// a um analisador de XML:
xr.setContentHandler(analisador);
xr.setErrorHandler(analisador);
for (int i = 0; i < args.length; i++) {
// le os arquivos passados via linha de comando:
FileReader r = new FileReader(args[i]);

// Para analisar um arquivo, necessrio analisar


// (parse) uma instncia de InputSource,
// com o FileReader como argumento:
xr.parse(new InputSource(r));

Baixe o cdigo-fonte acima neste link:


http://wiki.sintectus.com/pub/GrupoJava/SlidesProcessandoXMLComJava/An
alisaForm.java

11 - Para saber mais

XML na plataforma java:


http://java.sun.com/xml/
XML DOM Tutorial:
http://www.w3schools.com/dom/default.asp
Projeto SAX:
http://www.saxproject.org

http://www.saxproject.org/quickstart.html
Processing XML with Java de Elliotte Rusty Harold:
http://www.cafeconleche.org/books/xmljava/chapters/index.html
http://www.cafeconleche.org/books/xmljava/chapters/ch06.html
Parseando um XML com o SAX por Guilherme Silveira:
http://www.guj.com.br/java.tutorial.artigo.15.1.guj