Sistemas de Informação: XML- Java

Propaganda
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 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
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;
Verifica o
displayText[numberLines] += "<";
Cria cada um dos nós
número de
displayText[numberLines] += node.getNodeName();
recuperando seu nome
atributos do nó,
int length = (node.getAttributes() != null) ?
cria um vetor
node.getAttributes().getLength() : 0;
de atributos e
Attr attributes[] = new Attr[length];
itera sobre ele
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 no
displayText[numberLines] += "=\"";
vetor
displayText[numberLines] += attribute.getNodeValue();
displayText[numberLines] += "\"";
}
displayText[numberLines] += ">";
numberLines++;
 JCFJ
Cria a saída para
representar 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 de processamento 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 na saída
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 += "
";
A 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
Declaração de 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
do seguinte modo: 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.*;
Igual ao
primeiro
exemplo
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, utilizando
um método da API
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 do elemento
} catch (Exception e) {
e constrói o string de apresentação,
e.printStackTrace(System.err);
usando o método childLoop
}
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
Apresenta o conteúdo
M
exemplo anterior
do elemento
}
}
 JCFJ
14
XML
Java e SAX
Com SAX o processador
trabalha sobre o documento e
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
 JCFJ
ch17_01.xml
Sistemas de Informação
ao encontrar um nó, chama
<?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;
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
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
diferentes nós.
Cria uma fábrica para a criação
do parser SAX
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 uma
if (data != null && data.length() > 0) {
instrução de processamento
displayText[numberLines] += ' ';
Observar que os parâmetros já são
displayText[numberLines] += data;
passados automaticamente
}
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/javase/6/docs/api/org/xml/sax/helpers/DefaultHandler.html
 JCFJ
22
XML – XML, Java e DOM
Encontrando Elementos pelo Nome (SAX)
package ismt;
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 busca pelo 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
}
Se a variável displayBoolean for
if (displayBoolean){
verdadeira o elemento será
displayText[numberLines] = indentation;
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;
displayText[numberLines] += characterData;
numberLines++;
}
Se a variável displayBoolean
}
for verdadeira 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
}
buscas
 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
exemplo anterior
27
XML
APIs para Manipulação de XML
Existem diversas API para a serialização de objetos Java como documentos XML Uma bastante interessante é a Simple – XML Serialization:
Sistemas de Informação
http://simple.sourceforge.net/home.php
APIs como esta podem ser usadas para a troca de informações entre sistema criando e
lendo de forma bastante simples documentos XML que representam os objetos de
uma aplicação.
Para maiores informações:
http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php
 JCFJ
28
XML
Exercícios
Exercíício 1:
Exerc
Sistemas de Informação
Compilar os programas, analisar o código e verificar 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 elemento, o
programa deve escrever na saída de texto == > Encontrei o Thomas < ==.
Exercí
Exercício 3:
Escrever um programa Java que leia o documento XML ch16_01.xml e que apresente uma
mensagem indicando quantos elementos do tipo senator existem no documento.
 JCFJ
Download