JCFJS
ist
e
m
a
s
d
e
In
fo
rm
a
çã
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
2S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLJava e XML
Documentos XML podem ser abordados de dois modos
– W3C DOM (Document Object Model):
documento tratado como uma árvore de
nós
– SAX (Simple API for XML):
documento tratado como um 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
Os elementos não são automaticamente mantidos na
memória
JCFJ 3S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer 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> c h 1 6 _ 0 1 .x m l – XML, Java e DOM 4S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (DOM)
package ismt;import javax.xml.parsers.*; import org.w3c.dom.*;
public class Ch16_02 {
static String displayText[] = new String[1000]; static int numberLines = 0;
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]); childLoop(document, ""); } catch (Exception e) { e.printStackTrace(System.err); } C h 1 6 _ 0 2 .j a v a
Objeto que é criado para fazer a leitura do documento XML.
Objeto que é criado para realizar o parsing
do documento XML.
Lê o nome documento XML que será analisado e cria o DOM.
Método que irá manipular o DOM.
JCFJS
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
Ler um Documento XML com Java (DOM)
Mfor(int loopIndex = 0; loopIndex < numberLines; loopIndex++){ System.out.println(displayText[loopIndex]);
} }
public static void childLoop(Node node, String indentation) {
if (node == null) { return;
}
int type = node.getNodeType(); switch (type) {
case Node.DOCUMENT_NODE: {
displayText[numberLines] = indentation;
displayText[numberLines] += "<?xml version=\"1.0\" encoding=\""+ "UTF-8" + "\"?>"; numberLines++; childLoop(((Document)node).getDocumentElement(), ""); break; } C h 1 6 _ 0 2 .j a v a – c o n ti n u a ç ã o .. . Apresenta o documento após ele ter sido criado Se o documento estiver
vazio retorna
Recupera o tipo do nó Se o nó for o indicativo de documento adiciona o prólogo a displayText
Chama childLoop com o nó filho do nó tratado A partir do tipo do nó (tabela transp. 10) executa tarefas específicas 6
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (DOM)
Mcase Node.ELEMENT_NODE: {
displayText[numberLines] = indentation; displayText[numberLines] += "<";
displayText[numberLines] += node.getNodeName(); 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); }
for (int loopIndex = 0; loopIndex < attributes.length; loopIndex++) { Attr attribute = attributes[loopIndex];
displayText[numberLines] += " "; displayText[numberLines] += attribute.getNodeName(); displayText[numberLines] += "=\""; displayText[numberLines] += attribute.getNodeValue(); displayText[numberLines] += "\""; } displayText[numberLines] += ">"; numberLines++; C h 1 6 _ 0 2 .j a v a – c o n ti n u a ç ã o .. . – XML, Java e DOM
Cria cada um dos nós recuperando seu nome Elemento é do tipo nó
Cria a saída para representar o atributo. Verifica o número de atributos do nó, cria um vetor de atributos e itera sobre ele
Armazena os atributos no vetor
JCFJ 7S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (DOM)
MNodeList childNodes = node.getChildNodes(); if (childNodes != null) {
length = childNodes.getLength(); indentation += " ";
for (int loopIndex = 0; loopIndex < length; loopIndex++ ) { childLoop(childNodes.item(loopIndex), indentation); } } break; } 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; } C h 1 6 _ 0 2 .j a v a – c o n ti n u a ç ã o .. . – XML, Java e DOM
Verifica se o nó tem filhos
Verifica o número de filhos do nó
Para cada um dos filhos chama recursivamente o método
Adiciona a saída o conteúdo (sem espaços) do nó de texto se ele for válido
8
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (DOM)
Mcase 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++; break; } case Node.CDATA_SECTION_NODE: { displayText[numberLines] = indentation; displayText[numberLines] += "<![CDATA["; displayText[numberLines] += node.getNodeValue(); displayText[numberLines] += "]]>"; numberLines++; break; } } C h 1 6 _ 0 2 .j a v a – c o n ti n u a ç ã o .. . – XML, Java e DOM
As instruções de processamento são simplesmente copiadas apropriadamente na saída (<? --- ?>)
Sessões CDATA são simplesmente copiadas na saída
JCFJS
ist
e
m
a
s
d
e
In
fo
rm
a
çã
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 += " "; } } } C h 1 6 _ 0 2 .j a v a – c o n ti n u a ç ã o .. . A o elemento de fechamento ao marcador 10S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLCampos do Objeto Node
Um nó de texto
static short TEXT_NODE
Uma instrução de processamento
static short PROCESSING_INSTRUCTION_NODE
Uma notação
static short NOTATION_NODE
Um referência a entidade
static short ENTITY_REFERENCE_NODE
Uma entidade
static short ENTITY_NODE
Um elemento
static short ELEMENT_NODE
Um DTD
static short DOCUMENT_TYPE_NODE
Declaração de um documento
static short DOCUMENT_NODE
Um fragmento de documento
static short DOCUMENT_FRAGMENT_NODE
Um comentário
static short COMMENT_NODE
Uma seção CDATA
static short CDATA_SECTION_NODE
Um atributo
static short ATTRIBUTE_NODE
Define
Tipo de Campo
JCFJ 11S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLEncontrando Elementos pelo Nome (DOM)
Elementos específicos podem ser encontrados utilizando o método
getElementByTagName
Ex.: Procurar pelo elemento
senator
no documento XML
O programa deve ser chamado
do seguinte modo:
java Ch16_03 ch16_01.xml senator
– XML, Java e DOM 12
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLEncontrando Elementos pelo Nome (DOM)
package ismt;import javax.xml.parsers.*; import org.w3c.dom.*;
public class Ch16_03 {
static String displayText[] = new String[1000]; static int numberLines = 0;
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]);
NodeList nodeList = document.getElementsByTagName(args[1]);
C h 1 6 _ 0 3 .j a v a
Semelhante ao exemplo anterior mas executando somente para um nó específico
– XML, Java e DOM
Recupera uma lista de nós, do tipo especificado, utilizando um método da API
Igual ao primeiro exemplo
JCFJS
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
Encontrando Elementos pelo Nome (DOM)
Mif (nodeList != null) {
for (int loopIndex = 0; loopIndex < nodeList.getLength(); loopIndex++ ) { childLoop(nodeList.item(loopIndex), ""); } } } catch (Exception e) { e.printStackTrace(System.err); }
for(int loopIndex = 0; loopIndex < numberLines; loopIndex++){ System.out.println(displayText[loopIndex]);
} }
public static void childLoop(Node node, String indentation) { M M } } C h 1 6 _ 0 3 .j a v a – c o n ti n u a ç ã o .. . Semelhante ao exemplo anterior
Itera sobre a lista de nós do elemento e constrói o string de apresentação, usando o método childLoop
Apresenta o conteúdo do elemento 14
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLJava e SAX
Com SAX o processador
trabalha sobre o documento e
ao encontrar um nó, chama
um método específico para
realizar o tratamento
SAX é dirigido por eventos,
fazendo com que os métodos
sejam chamados quando o
processador encontrar os
elementos específicos
<?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> c h 1 7 _ 0 1 .x m l
JCFJ 15S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (SAX)
package ismt;import java.io.*; import org.xml.sax.*;
import javax.xml.parsers.*;
import 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]);
for (int loopIndex = 0; loopIndex < numberLines; loopIndex++) { System.out.println(displayText[loopIndex]); } } C h 1 7 _ 0 2 .j a v a
Cria um objeto do tratador Chama o método que constrói a saída para o documento passado como argumento
Ch17_02 é 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
Apresenta a saída 16
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (SAX)
M
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) {}
}
public void startDocument() {
displayText[numberLines] = indentation;
displayText[numberLines] += "<?xml version=\"1.0\" encoding=\""+ "UTF-8" + "\"?>"; numberLines++; } C h 1 7 _ 0 2 .j a v a – c o n ti n u a ç ã o .. .
Cria um tratador para o documento. Este elemento irá indicar ao SAX qual objeto chamar quando encontrar os diferentes nós.
Cria uma fábrica para a criação do parser SAX
Cria o parser que irá realizar o parsing do documento
Realiza o parsing do documento
Método chamado quando o início do documento é encontrado
JCFJS
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
Ler um Documento XML com Java (SAX)
Mpublic void processingInstruction(String target, String data) {
displayText[numberLines] = indentation; displayText[numberLines] += "<?";
displayText[numberLines] += target; if (data != null && data.length() > 0) {
displayText[numberLines] += ' '; displayText[numberLines] += data; } displayText[numberLines] += "?>"; numberLines++; } C h 1 7 _ 0 2 .j a v a – c o n ti n u a ç ã o .. .
Método chamado para manipular uma instrução de processamento
Observar que os parâmetros já são passados automaticamente 18
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (SAX)
Mpublic void startElement(String uri, String localName, String qualifiedName, Attributes attributes) { displayText[numberLines] = indentation; indentation += " "; displayText[numberLines] += '<'; displayText[numberLines] += qualifiedName; if (attributes != null) {
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++; } C h 1 7 _ 0 2 .j a v a – c o n ti n u a ç ã o .. .
Método chamado para manipular um elemento de início Observar que os parâmetros já são passados automaticamente
Se existirem atributos constrói sua apresentação
Verifica se o elemento tem atributos
JCFJ 19S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (SAX)
Mpublic 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; displayText[numberLines] += characterData; numberLines++;
} }
public void endElement(String uri, String localName, String qualifiedName) {
indentation = indentation.substring(0, indentation.length() - 4); displayText[numberLines] = indentation; displayText[numberLines] += "</"; displayText[numberLines] += qualifiedName; displayText[numberLines] += '>'; numberLines++; } C h 1 7 _ 0 2 .j a v a – c o n ti n u a ç ã o .. .
Método utilizado para manipular texto
Posição em que começa o texto do elemento
Método utilizado para manipular o final do elemento
20
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLLer um Documento XML com Java (SAX)
Mpublic void warning(SAXParseException exception) {
System.err.println("Warning: " + exception.getMessage()); }
public void error(SAXParseException exception) {
System.err.println("Error: " + exception.getMessage()); }
public void fatalError(SAXParseException exception) { System.err.println("Fatal error: " + exception.getMessage()); } } C h 1 7 _ 0 2 .j a v a – c o n ti n u a ç ã o .. .
Métodos utilizados para manipular os erros que possam ocorrer durante a manipulação do documento XML
JCFJS
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
Métodos da Classe DefaultHandler
Manipula o início de um
namespace
void startPrefixMapping(String prefix, String uri)
Manipula o início de um elemento
void startElement(String uri, String localName, String
qName, Attributes attributes)
Manipula início do documento
void startDocument
Manipula inst. processamento
void processingInstruction(String target, String data)
Manipula “espaços descartáveis”
void ignorableWhitespace(char[] ch, int start, int length)
Avisa de um erro fatal
void fatalError(SAXParseException e)
Manipula um erro recuperável
void error(SAXParseException e)
Manipula o final do elemento
void endElement(String uri, String localName, String qName)
Manipula o final do documento
void endocument()
Manipula nós de texto
characters(char[] ch, int start, int length)
Construtor
DefaultHandler()
Objetivo
Método
Outros existem: consultar
http://java.sun.com/javase/6/docs/api/org/xml/sax/helpers/DefaultHandler.html
22S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLEncontrando Elementos pelo Nome (SAX)
– XML, Java e DOM package ismt; import java.io.*; import org.xml.sax.*; import javax.xml.parsers.*; import org.xml.sax.helpers.DefaultHandler; public class Ch17_03 extends DefaultHandler {
static int numberLines = 0; static String indentation = "";
static String displayText[] = new String[1000]; 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]);
for(int index = 0; index < numberLines; index++){ System.out.println(displayText[index]); } } C h 1 7 _ 0 3 .j a v a
Argumento que identifica o elemento que será procurado
Variáveis que serão usadas para a busca pelo elemento
JCFJ 23S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLEncontrando Elementos pelo Nome (SAX)
– XML, Java e DOM
M
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) {} } C h 1 7 _ 0 3 .j a v a – c o n ti n u a ç ã o .. . Idêntico ao anterior 24
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLEncontrando Elementos pelo Nome (SAX)
– XML, Java e DOM
M
public void startElement(String uri, String localName, String qualifiedName, Attributes attributes) { if(qualifiedName.equals(findNode)){ displayBoolean=true; } if (displayBoolean){ displayText[numberLines] = indentation; indentation += " "; displayText[numberLines] += '<'; displayText[numberLines] += qualifiedName; if (attributes != null) {
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++; } } C h 1 7 _ 0 3 .j a v a – c o n ti n u a ç ã o .. .
Verifica se o nó é o que se está procurando. Caso seja, define displayBoolean para verdadeiro Se a variável displayBoolean for verdadeira o elemento será inserido
JCFJS
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
Encontrando Elementos pelo Nome (SAX)
Mpublic 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; displayText[numberLines] += characterData; numberLines++; } } }
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++; } if(qualifiedName.equals(findNode)){ displayBoolean=false; } } C h 1 7 _ 0 3 .j a v a – c o n ti n u a ç ã o .. .
Após ter encontrado o nó do final do elemento procurado, define-se displayBoolean para false para as próximas buscas
Se a variável displayBoolean for verdadeira o elemento de texto será inserido
26
S
ist
e
m
a
s
d
e
In
fo
rm
a
çã
o
XMLEncontrando Elementos pelo Nome (SAX)
– XML, Java e DOM
M
public void warning(SAXParseException exception) {
System.err.println("Warning: " + exception.getMessage()); }
public void error(SAXParseException exception) {
System.err.println("Error: " + exception.getMessage()); }
public void fatalError(SAXParseException exception) { System.err.println("Fatal error: " + exception.getMessage()); } } C h 1 7 _ 0 3 .j a v a – c o n ti n u a ç ã o .. . Semelhante ao do exemplo anterior