1
XML
Sistemas de Informação
Sistemas de Informação:
XML- Java
Todos os exemplos bem como o conteúdo teórico
tem por base o livro:
Steven Holzner, SAMS Teach Yourself XML,
SAMS Publishing, 2004
JCFJ
2
XML
Java e XML
Documentos XML podem ser abordados de dois modos
– W3C DOM (Document Object Model): documento tratado como uma árvore de
Sistemas de Informação
nós
– SAX (Simple API for XML): documento tratado com uma arquivo texto
Com DOM é necessário construir na memória a árvore completa que
representa o documento XML para depois se poder manipulá-lo
Com SAX os elementos são recuperados a medida que o documento
XML é lido mas os elementos não são automaticamente mantidos na
memória
JCFJ
3
XML – XML, Java e DOM
ch16_01.xml
Sistemas de Informação
Ler um Documento XML com Java (DOM)
<?xml version="1.0" encoding="UTF-8"?>
<session>
<committee type="monetary">
<title>Finance</title>
<number>17</number>
<subject>Donut Costs</subject>
<date>7/15/2005</date>
<attendees>
<senator status="present">
<firstName>Thomas</firstName>
<lastName>Smith</lastName>
</senator>
<senator status="absent">
<firstName>Frank</firstName>
<lastName>McCoy</lastName>
</senator>
<senator status="present">
<firstName>Jay</firstName>
<lastName>Jones</lastName>
</senator>
</attendees>
</committee>
</session>
JCFJ
4
XML – XML, Java e DOM
Ler um Documento XML com Java (DOM)
public class Ch16_02
{
static String displayText[] = new String[1000];
static int numberLines = 0;
Ch16_02.java
Sistemas de Informação
package ismt;
import javax.xml.parsers.*;
import org.w3c.dom.*;
Objeto que é criado para fazer a
leitura do documento XML.
public static void main(String args[])
{
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
}
catch (ParserConfigurationException e) {}
Document document = null;
document = builder.parse(args[0]);
Objeto que é criado
para realizar o parsing
do documento XML.
Lê o nome documento XML que
será analisado e cria o DOM.
childLoop(document, "");
} catch (Exception e) {
e.printStackTrace(System.err);
}
JCFJ
Método que irá
manipular o DOM.
5
XML – XML, Java e DOM
Ler um Documento XML com Java (DOM)
M
Ch16_02.java – continuação...
Sistemas de Informação
for(int loopIndex = 0; loopIndex < numberLines; loopIndex++){
System.out.println(displayText[loopIndex]);
}
Apresenta o documento
}
após ele ter sido criado
public static void childLoop(Node node, String indentation)
{
Se o documento estiver
if (node == null) {
vazio retorna
return;
}
Recupera o tipo do nó
int type = node.getNodeType();
Se o nó for o indicativo de documento
switch (type) {
adiciona o prólogo a displayText
case Node.DOCUMENT_NODE: {
displayText[numberLines] = indentation;
displayText[numberLines] += "<?xml version=\"1.0\" encoding=\""+
"UTF-8" + "\"?>";
A partir do tipo do
numberLines++;
nó (tabela transp.
childLoop(((Document)node).getDocumentElement(), "");
10) executa tarefas
break;
específicas
}
Chama childLoop com o nó
filho do nó tratado
JCFJ
6
XML – XML, Java e DOM
Ler um Documento XML com Java (DOM)
Elemento é do tipo nó
case Node.ELEMENT_NODE: {
displayText[numberLines] = indentation;
displayText[numberLines] += "<";
Verifica o número
Cria cada um dos nós
displayText[numberLines] += node.getNodeName();
de atributos do nó
recuperando seu nome
int length = (node.getAttributes() != null) ?
node.getAttributes().getLength() : 0;
Attr attributes[] = new Attr[length];
for (int loopIndex = 0; loopIndex < length; loopIndex++) {
attributes[loopIndex] =
(Attr)node.getAttributes().item(loopIndex);
}
Ch16_02.java – continuação...
Sistemas de Informação
M
for (int loopIndex = 0; loopIndex < attributes.length; loopIndex++) {
Attr attribute = attributes[loopIndex];
displayText[numberLines] += " ";
Armazena os
displayText[numberLines] += attribute.getNodeName();
atributos num
displayText[numberLines] += "=\"";
array
displayText[numberLines] += attribute.getNodeValue();
displayText[numberLines] += "\"";
}
displayText[numberLines] += ">";
numberLines++;
JCFJ
Cria a saída para o
atributo.
7
XML – XML, Java e DOM
Ler um Documento XML com Java (DOM)
Verifica se o nó tem filhos
M
Ch16_02.java – continuação...
Sistemas de Informação
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
Verifica o número
length = childNodes.getLength();
de filhos do nó
indentation += "
";
for (int loopIndex = 0; loopIndex < length; loopIndex++ ) {
childLoop(childNodes.item(loopIndex), indentation);
}
}
Para cada um dos filhos chama
break;
recursivamente o método
}
case Node.TEXT_NODE: {
displayText[numberLines] = indentation;
String trimmedText = node.getNodeValue().trim();
if(trimmedText.indexOf("\n") < 0 && trimmedText.length() > 0) {
displayText[numberLines] += trimmedText;
numberLines++;
}
break;
}
Adiciona a saída o conteúdo
(sem espaços) do nó de texto
se ele for válido
JCFJ
XML – XML, Java e DOM
Ler um Documento XML com Java (DOM)
Ch16_02.java – continuação...
Sistemas de Informação
M
JCFJ
case Node.PROCESSING_INSTRUCTION_NODE: {
displayText[numberLines] = indentation;
displayText[numberLines] += "<?";
displayText[numberLines] += node.getNodeName();
String text = node.getNodeValue();
if (text != null && text.length() > 0) {
displayText[numberLines] += text;
}
displayText[numberLines] += "?>";
numberLines++;
As instruções são processadas são
break;
simplesmente copiadas apropriadamente na
}
saída (<? --- ?>)
case Node.CDATA_SECTION_NODE: {
displayText[numberLines] = indentation;
displayText[numberLines] += "<![CDATA[";
displayText[numberLines] += node.getNodeValue();
displayText[numberLines] += "]]>";
numberLines++;
break;
}
}
Sessões CDATA são simplesmente
copiadas apropriadamente
8
9
XML – XML, Java e DOM
Ch16_02.java – continuação...
Sistemas de Informação
Ler um Documento XML com Java (DOM)
M
if (type == Node.ELEMENT_NODE) {
displayText[numberLines] = indentation.substring(0,
indentation.length() - 4);
displayText[numberLines] += "</";
displayText[numberLines] += node.getNodeName();
displayText[numberLines] += ">";
numberLines++;
indentation += "
";
}
Ao final do processamento adiciona o
}
elemento de fechamento ao marcador
}
JCFJ
10
XML
Campos do Objeto Node
Sistemas de Informação
Tipo de Campo
Define
static short ATTRIBUTE_NODE
Um atributo
static short CDATA_SECTION_NODE
Uma seção CDATA
static short COMMENT_NODE
Um comentário
static short DOCUMENT_FRAGMENT_NODE
Um fragmento de documento
static short DOCUMENT_NODE
Um documento
static short DOCUMENT_TYPE_NODE
Um DTD
static short ELEMENT_NODE
Um elemento
static short ENTITY_NODE
Uma entidade
static short ENTITY_REFERENCE_NODE
Um referência a entidade
static short NOTATION_NODE
Uma notação
static short PROCESSING_INSTRUCTION_NODE
Uma instrução de processamento
static short TEXT_NODE
Um nó de texto
JCFJ
11
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (DOM)
Elementos específicos podem ser encontrados utilizando o método
getElementByTagName Ex.: Procurar pelo elemento senator
Sistemas de Informação
no documento XML O programa deve ser chamado
java Ch16_03 ch16_01.xml senator
JCFJ
12
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (DOM)
package ismt;
Semelhante ao exemplo anterior
mas executando somente para um
nó específico
public class Ch16_03
{
static String displayText[] = new String[1000];
static int numberLines = 0;
Ch16_03.java
Sistemas de Informação
import javax.xml.parsers.*;
import org.w3c.dom.*;
public static void main(String args[])
{
try {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
}
catch (ParserConfigurationException e) {}
Recupera uma lista de
nós, do tipo especificado
Document document = null;
document = builder.parse(args[0]);
NodeList nodeList = document.getElementsByTagName(args[1]);
JCFJ
13
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (DOM)
if (nodeList != null) {
for (int loopIndex = 0; loopIndex < nodeList.getLength();
loopIndex++ ) {
childLoop(nodeList.item(loopIndex), "");
}
}
Itera sobre a lista de nós específicos
} catch (Exception e) {
e constrói o string de apresentação
e.printStackTrace(System.err);
}
Ch16_03.java – continuação...
Sistemas de Informação
M
for(int loopIndex = 0; loopIndex < numberLines; loopIndex++){
System.out.println(displayText[loopIndex]);
}
}
public static void childLoop(Node node, String indentation)
{
M
Semelhante ao
M
exemplo anterior
}
}
JCFJ
14
XML
Java e SAX
Com SAX o processador
trabalha sobre o documento e
ele chama um método
específico que irá tratar o nó
SAX é dirigido por eventos de
tal modo que os métodos são
chamados quando o
processador encontra os
elementos específicos
JCFJ
ch17_01.xml
Sistemas de Informação
quando ele encontra um nó
<?xml version="1.0" encoding="UTF-8"?>
<session>
<committee type="monetary">
<title>Finance</title>
<number>17</number>
<subject>Donut Costs</subject>
<date>7/15/2005</date>
<attendees>
<senator status="present">
<firstName>Thomas</firstName>
<lastName>Smith</lastName>
</senator>
<senator status="absent">
<firstName>Frank</firstName>
<lastName>McCoy</lastName>
</senator>
<senator status="present">
<firstName>Jay</firstName>
<lastName>Jones</lastName>
</senator>
</attendees>
</committee>
</session>
15
XML
Ler um Documento XML com Java (SAX)
import
import
import
import
Ch17_02.java
Sistemas de Informação
package ismt;
A classe é uma sub-classe de um tratador padrão SAX. Este tratador
tem uma série de métodos (transp. 21) que são chamados em resposta
a eventos (nós específicos encontrados) Métodos específicos devem
ser reimplementados para manipular elementos específicos
java.io.*;
org.xml.sax.*;
javax.xml.parsers.*;
org.xml.sax.helpers.DefaultHandler;
public class Ch17_02 extends DefaultHandler
{
static int numberLines = 0;
static String indentation = "";
static String displayText[] = new String[1000];
public static void main(String args[])
{
Ch17_02 parser = new Ch17_02();
parser.childLoop(args[0]);
Cria um objeto do tratador
Chama o método que constrói a
saída para o documento passado
como argumento
for(int loopIndex = 0; loopIndex < numberLines; loopIndex++){
System.out.println(displayText[loopIndex]);
}
}
Apresenta a saída
JCFJ
16
XML
Ler um Documento XML com Java (SAX)
Cria um tratador para o
documento. Este elemento irá
indicar ao SAX qual objeto chamar
quando encontrar os vários nós.
Define uma API que habilita a
aplicação a configurar e obter
um parser SAX baseado no
documento corrente
Ch17_02.java – continuação...
Sistemas de Informação
M
JCFJ
public void childLoop(String uri)
{
DefaultHandler saxHandler = this;
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
try {
Cria o parser que irá
SAXParser saxParser = saxFactory.newSAXParser();
realizar o parsing do
saxParser.parse(new File(uri), saxHandler);
documento
} catch (Throwable t) {}
}
Realiza o parsing do
documento
public void startDocument()
Método chamado quando o início
{
do documento é encontrado
displayText[numberLines] = indentation;
displayText[numberLines] += "<?xml version=\"1.0\" encoding=\""+
"UTF-8" + "\"?>";
numberLines++;
}
17
XML
Ler um Documento XML com Java (SAX)
public void processingInstruction(String target, String data)
{
displayText[numberLines] = indentation;
displayText[numberLines] += "<?";
displayText[numberLines] += target;
Método chamado para manipular
if (data != null && data.length() > 0) {
uma instrução de processamento
displayText[numberLines] += ' ';
displayText[numberLines] += data;
}
displayText[numberLines] += "?>";
numberLines++;
}
Ch17_02.java – continuação...
Sistemas de Informação
M
JCFJ
18
XML
Ler um Documento XML com Java (SAX)
Ch17_02.java – continuação...
Sistemas de Informação
M
public void startElement(String uri, String localName, String qualifiedName,
Attributes attributes)
Método chamado para manipular um
{
elemento de início Observar que
displayText[numberLines] = indentation;
os parâmetros já são passados
automaticamente
indentation += "
";
}
JCFJ
displayText[numberLines] += '<';
displayText[numberLines] += qualifiedName;
Verifica se o elemento
if (attributes != null) {
tem atributos
int numberAttributes = attributes.getLength();
for (int loopIndex = 0; loopIndex < numberAttributes; loopIndex++) {
displayText[numberLines] += ' ';
displayText[numberLines] += attributes.getQName(loopIndex);
displayText[numberLines] += "=\"";
displayText[numberLines] += attributes.getValue(loopIndex);
displayText[numberLines] += '"';
}
}
displayText[numberLines] += '>';
numberLines++;
Se existirem atributos constrói sua
apresentação
19
XML
Ler um Documento XML com Java (SAX)
Método utilizado para manipular texto
public void characters(char characters[], int start, int length)
{
String characterData = (new String(characters, start, length)).trim();
if(characterData.indexOf("\n") < 0 && characterData.length() > 0) {
displayText[numberLines] = indentation;
Posição em que
displayText[numberLines] += characterData;
começa o texto do
numberLines++;
elemento
}
}
Ch17_02.java – continuação...
Sistemas de Informação
M
public void endElement(String uri, String localName, String qualifiedName)
{
indentation = indentation.substring(0, indentation.length() - 4);
displayText[numberLines] = indentation;
displayText[numberLines] += "</";
Método utilizado para
displayText[numberLines] += qualifiedName;
manipular o final do elemento
displayText[numberLines] += '>';
numberLines++;
}
JCFJ
20
XML
Ler um Documento XML com Java (SAX)
public void warning(SAXParseException exception)
{
System.err.println("Warning: " +
exception.getMessage());
}
Ch17_02.java – continuação...
Sistemas de Informação
M
public void error(SAXParseException exception)
{
System.err.println("Error: " +
exception.getMessage());
}
public void fatalError(SAXParseException exception)
{
System.err.println("Fatal error: " +
exception.getMessage());
}
}
JCFJ
Métodos utilizados para
manipular os erros que possam
ocorrer durante a manipulação
do documento XML
21
XML
Métodos da Classe DefaultHandler
Sistemas de Informação
Método
Objetivo
DefaultHandler()
Construtor
characters(char[] ch, int start, int length)
Manipula nós de texto
void endocument()
Manipula o final do documento
void endElement(String uri, String localName, String qName) Manipula o final do elemento
void error(SAXParseException e)
Manipula um erro recuperável
void fatalError(SAXParseException e)
Avisa de um erro fatal
void ignorableWhitespace(char[] ch, int start, int length)
Manipula “espaços descartáveis”
void processingInstruction(String target, String data)
Manipula inst. processamento
void startDocument
Manipula início do documento
void startElement(String uri, String localName, String
qName, Attributes attributes)
Manipula o início de um elemento
void startPrefixMapping(String prefix, String uri)
Manipula o início de um
namespace
Outros existem: consultar
http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/helpers/DefaultHandler.html
JCFJ
22
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (SAX)
Ch17_03.java
Sistemas de Informação
import
import
import
import
java.io.*;
org.xml.sax.*;
javax.xml.parsers.*;
org.xml.sax.helpers.DefaultHandler;
public class ch17_03 extends DefaultHandler
{
static int numberLines = 0;
static String indentation = "";
static String displayText[] = new String[1000];
Variáveis que serão usadas
para a procura do elemento
static boolean displayBoolean;
static String findNode;
public static void main(String args[])
{
ch17_03 obj = new ch17_03();
findNode = args[1];
obj.childLoop(args[0]);
Argumento que identifica o
elemento que será procurado
for(int index = 0; index < numberLines; index++){
System.out.println(displayText[index]);
}
}
JCFJ
23
XML – XML, Java e DOM
Ch17_03.java – continuação...
Sistemas de Informação
Encontrando Elementos pelo Nome (SAX)
M
Idêntico ao anterior
public void childLoop(String uri)
{
DefaultHandler saxHandler = this;
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = saxFactory.newSAXParser();
saxParser.parse(new File(uri), saxHandler);
} catch (Throwable t) {}
}
JCFJ
24
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (SAX)
M
Ch17_03.java – continuação...
Sistemas de Informação
public void startElement(String uri, String localName,
String qualifiedName, Attributes attributes)
Verifica se o nó é o que se está
{
procurando. Caso seja define
if(qualifiedName.equals(findNode)){
displayBoolean=true;
displayBoolean para verdadeiro
}
Somente se a variável
if (displayBoolean){
displayBoolean for verdadeira
displayText[numberLines] = indentation;
que o elemento será inserido
indentation += "
";
displayText[numberLines] += '<';
displayText[numberLines] += qualifiedName;
if (attributes != null) {
int numberAttributes = attributes.getLength();
for (int loopIndex = 0; loopIndex < numberAttributes; loopIndex++)
{
displayText[numberLines]
displayText[numberLines]
displayText[numberLines]
displayText[numberLines]
displayText[numberLines]
}
}
displayText[numberLines] += '>';
numberLines++;
}
}
JCFJ
+=
+=
+=
+=
+=
' ';
attributes.getQName(loopIndex);
"=\"";
attributes.getValue(loopIndex);
'"';
25
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (SAX)
public void characters(char characters[], int start, int length) {
if(displayBoolean){
String characterData = (new String(characters, start, length)).trim();
if(characterData.indexOf("\n") < 0 && characterData.length() > 0) {
displayText[numberLines] = indentation;
Somente se a variável
displayText[numberLines] += characterData;
displayBoolean for
numberLines++;
verdadeira que o
}
}
elemento de texto será
}
inserido
Ch17_03.java – continuação...
Sistemas de Informação
M
public void endElement(String uri, String localName, String qualifiedName)
{
if(displayBoolean){
indentation = indentation.substring(0, indentation.length() - 4);
displayText[numberLines] = indentation;
displayText[numberLines] += "</";
displayText[numberLines] += qualifiedName;
displayText[numberLines] += '>';
numberLines++;
Após ter encontrado o
}
nó do final do elemento
if(qualifiedName.equals(findNode)){
procurado define-se
displayBoolean=false;
displayBoolean para
}
false para as próximas
}
procuras
JCFJ
26
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (SAX)
public void warning(SAXParseException exception)
{
System.err.println("Warning: " +
exception.getMessage());
}
Ch17_03.java – continuação...
Sistemas de Informação
M
public void error(SAXParseException exception)
{
System.err.println("Error: " +
exception.getMessage());
}
public void fatalError(SAXParseException exception)
{
System.err.println("Fatal error: " +
exception.getMessage());
}
}
JCFJ
Semelhante ao do
exemploanterior
27
XML
Exercícios
Exercí
Exercício 1:
Sistemas de Informação
Compilar os programas e verificar a a saída de cada um deles.
Exercí
Exercício 2:
Escrever um programa Java que leia o documento XML ch16_01.xml e que procure o
elemento <firstName>Thomas</firstName>. Quando o encontrar o programa deve
escrever na saída de texto == > Encontrei o Thomas < ==.
JCFJ