XL 1 : XL- Java Todos os exemplos bem como o conteúdo teórico tem por base o livro: Steven Holzner, SAS Teach Yourself XL, SAS Publishing, 2004 XL Java e XL 2 Documentos XL podem ser abordados de dois modos W3C DO (Document Object odel): documento tratado como uma árvore de nós SAX (Simple API for XL): documento tratado como um arquivo texto Com DO é necessário construir na memória a árvore completa que representa o documento XL para depois se poder manipulá-lo Com SAX os elementos são recuperados a medida que o documento XL é lido Os elementos não são automaticamente mantidos na memória
XL XL, Java e DO 3 Ler um Documento XL com Java (DO) ch16_01.xml <?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>ccoy</lastname> </senator> <senator status="present"> <firstname>jay</firstname> <lastname>jones</lastname> </senator> </attendees> </committee> </session> XL XL, Java e DO Ler um Documento XL com Java (DO) package ismt; import javax.xml.parsers.*; import org.w3c.dom.*; 4 Ch16_02.java 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) Objeto que é criado para fazer a leitura do documento XL. Objeto que é criado para realizar o parsing do documento XL. Document document = null; document = builder.parse(args[0]); childloop(document, ""); catch (Exception e) e.printstacktrace(system.err); Lê o nome documento XL que será analisado e cria o DO. étodo que irá manipular o DO.
Ch16_02.java continuação... XL XL, Java e DO Ler um Documento XL com Java (DO) 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) A partir do tipo do nó (tabela transp. 10) executa tarefas específicas if (node == null) return; int type = node.getnodetype(); switch (type) case Node.DOCUENT_NODE: 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 displaytext[numberlines] += "<?xml version=\"1.0\" encoding=\""+ "UTF-8" + "\"?>"; childloop(((document)node).getdocumentelement(), ""); break; Chama childloop com o nó filho do nó tratado 5 XL XL, Java e DO Ler um Documento XL com Java (DO) Verifica o número de atributos do nó, cria um vetor de atributos e itera sobre ele Ch16_02.java continuação... case Node.ELEENT_NODE: displaytext[numberlines] += "<"; displaytext[numberlines] += node.getnodename(); Armazena os atributos no vetor Elemento é do tipo nó 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] += ">"; 6 Cria cada um dos nós recuperando seu nome Cria a saída para representar o atributo.
Ch16_02.java continuação... XL XL, Java e DO Ler um Documento XL com Java (DO) Verifica o número de filhos do nó NodeList childnodes = node.getchildnodes(); if (childnodes!= null) length = childnodes.getlength(); indentation += " "; for (int loopindex = 0; loopindex < length; loopindex++ ) childloop(childnodes.item(loopindex), indentation); break; Verifica se o nó tem filhos Para cada um dos filhos chama recursivamente o método case Node.TEXT_NODE: String trimmedtext = node.getnodevalue().trim(); if(trimmedtext.indexof("\n") < 0 && trimmedtext.length() > 0) displaytext[numberlines] += trimmedtext; break; Adiciona a saída o conteúdo (sem espaços) do nó de texto se ele for válido 7 XL XL, Java e DO 8 Ler um Documento XL com Java (DO) Ch16_02.java continuação... case Node.PROCESSING_INSTRUCTION_NODE: displaytext[numberlines] += "<?"; displaytext[numberlines] += node.getnodename(); String text = node.getnodevalue(); if (text!= null && text.length() > 0) displaytext[numberlines] += text; displaytext[numberlines] += "?>"; break; As instruções de processamento são simplesmente copiadas apropriadamente na saída (<? ---?>) case Node.CDATA_SECTION_NODE: displaytext[numberlines] += "<![CDATA["; displaytext[numberlines] += node.getnodevalue(); displaytext[numberlines] += "]]>"; break; Sessões CDATA são simplesmente copiadas na saída
XL XL, Java e DO 9 Ler um Documento XL com Java (DO) Ch16_02.java continuação... if (type == Node.ELEENT_NODE) displaytext[numberlines] = indentation.substring(0, indentation.length() - 4); displaytext[numberlines] += "</"; displaytext[numberlines] += node.getnodename(); displaytext[numberlines] += ">"; indentation += " "; A o elemento de fechamento ao marcador XL Campos do Objeto Node 10 Tipo de Campo static short ATTRIBUTE_NODE static short CDATA_SECTION_NODE static short COENT_NODE static short DOCUENT_FRAGENT_NODE static short DOCUENT_NODE static short DOCUENT_TYPE_NODE static short ELEENT_NODE static short ENTITY_NODE static short ENTITY_REFERENCE_NODE static short NOTATION_NODE static short PROCESSING_INSTRUCTION_NODE static short TEXT_NODE Define Um atributo Uma seção CDATA Um comentário Um fragmento de documento Declaração de um documento Um DTD Um elemento Uma entidade Um referência a entidade Uma notação Uma instrução de processamento Um nó de texto
XL XL, Java e DO 11 Encontrando Elementos pelo Nome (DO) Elementos específicos podem ser encontrados utilizando o método getelementbytagname Ex.: Procurar pelo elemento senator no documento XL O programa deve ser chamado do seguinte modo: java Ch16_03 ch16_01.xml senator Ch16_03.java Igual ao primeiro exemplo XL XL, Java e DO Encontrando Elementos pelo Nome (DO) 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]); Semelhante ao exemplo anterior mas executando somente para um nó específico Recupera uma lista de nós, do tipo especificado, utilizando um método da API NodeList nodelist = document.getelementsbytagname(args[1]); 12
XL XL, Java e DO 13 Encontrando Elementos pelo Nome (DO) Ch16_03.java continuação... if (nodelist!= null) for (int loopindex = 0; loopindex < nodelist.getlength(); loopindex++ ) childloop(nodelist.item(loopindex), ""); catch (Exception e) e.printstacktrace(system.err); Itera sobre a lista de nós do elemento e constrói o string de apresentação, usando o método childloop for(int loopindex = 0; loopindex < numberlines; loopindex++) System.out.println(displayText[loopIndex]); public static void childloop(node node, String indentation) Semelhante ao Apresenta o conteúdo exemplo anterior do elemento XL Java e SAX 14 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 ch17_01.xml <?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>ccoy</lastname> </senator> <senator status="present"> <firstname>jay</firstname> <lastname>jones</lastname> </senator> </attendees> </committee> </session>
XL Ler um Documento XL com Java (SAX) 15 Ch17_02.java 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 package ismt; a eventos (nós específicos encontrados) étodos específicos devem ser reimplementados para manipular elementos específicos 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]); 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 XL Ler um Documento XL com Java (SAX) 16 Ch17_02.java continuação... public void childloop(string uri) DefaultHandler saxhandler = this; SAXParserFactory saxfactory = SAXParserFactory.newInstance(); Cria um tratador para o documento. Este elemento irá indicar ao SAX qual objeto chamar quando encontrar os diferentes nós. try SAXParser saxparser = saxfactory.newsaxparser(); saxparser.parse(new File(uri), saxhandler); catch (Throwable t) Realiza o parsing do documento Cria uma fábrica para a criação do parser SAX Cria o parser que irá realizar o parsing do documento public void startdocument() étodo chamado quando o início do documento é encontrado displaytext[numberlines] += "<?xml version=\"1.0\" encoding=\""+ "UTF-8" + "\"?>";
XL Ler um Documento XL com Java (SAX) 17 Ch17_02.java continuação... public void processinginstruction(string target, String data) displaytext[numberlines] += "<?"; displaytext[numberlines] += target; if (data!= null && data.length() > 0) displaytext[numberlines] += ' '; displaytext[numberlines] += data; displaytext[numberlines] += "?>"; étodo chamado para manipular uma instrução de processamento Observar que os parâmetros já são passados automaticamente Ch17_02.java continuação... XL Ler um Documento XL com Java (SAX) public void startelement(string uri, String localname, String qualifiedname, Attributes attributes) étodo chamado para manipular um elemento de início Observar que os parâmetros já são passados automaticamente 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] += '>'; Se existirem atributos constrói sua apresentação Verifica se o elemento tem atributos 18
Ch17_02.java continuação... XL Ler um Documento XL com Java (SAX) 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] += characterdata; public void endelement(string uri, String localname, String qualifiedname) indentation = indentation.substring(0, indentation.length() - 4); étodo utilizado para manipular texto displaytext[numberlines] += "</"; displaytext[numberlines] += qualifiedname; displaytext[numberlines] += '>'; Posição em que começa o texto do elemento étodo utilizado para manipular o final do elemento 19 XL Ler um Documento XL com Java (SAX) 20 Ch17_02.java continuação... public void warning(saxparseexception exception) System.err.println("Warning: " + exception.getessage()); public void error(saxparseexception exception) System.err.println("Error: " + exception.getessage()); public void fatalerror(saxparseexception exception) System.err.println("Fatal error: " + exception.getessage()); étodos utilizados para manipular os erros que possam ocorrer durante a manipulação do documento XL
XL étodos da Classe DefaultHandler 21 DefaultHandler() void endocument() void startdocument étodo characters(char[] ch, int start, int length) void endelement(string uri, String localname, String qname) void error(saxparseexception e) void fatalerror(saxparseexception e) void ignorablewhitespace(char[] ch, int start, int length) void processinginstruction(string target, String data) void startelement(string uri, String localname, String qname, Attributes attributes) void startprefixapping(string prefix, String uri) Construtor Objetivo anipula nós de texto anipula o final do documento anipula o final do elemento anipula um erro recuperável Avisa de um erro fatal anipula espaços descartáveis anipula inst. processamento anipula início do documento anipula o início de um elemento anipula o início de um namespace Outros existem: consultar http://java.sun.com/javase/6/docs/api/org/xml/sax/helpers/defaulthandler.html XL XL, Java e DO Encontrando Elementos pelo Nome (SAX) package ismt; import java.io.*; import org.xml.sax.*; import javax.xml.parsers.*; import org.xml.sax.helpers.defaulthandler; 22 Ch17_03.java 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]); Variáveis que serão usadas para a busca pelo elemento Argumento que identifica o elemento que será procurado for(int index = 0; index < numberlines; index++) System.out.println(displayText[index]);
XL XL, Java e DO 23 Encontrando Elementos pelo Nome (SAX) Ch17_03.java continuação... 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) Ch17_03.java continuação... XL XL, Java e DO Encontrando Elementos pelo Nome (SAX) public void startelement(string uri, String localname, String qualifiedname, Attributes attributes) Verifica se o nó é o que se está if(qualifiedname.equals(findnode)) procurando. Caso seja, define displayboolean=true; displayboolean para verdadeiro if (displayboolean) Se a variável displayboolean for verdadeira o elemento será indentation += " "; inserido 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] += '>'; 24
Ch17_03.java continuação... XL XL, Java e DO 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] += characterdata; Se a variável displayboolean for verdadeira o elemento de texto será inserido public void endelement(string uri, String localname, String qualifiedname) if(displayboolean) indentation = indentation.substring(0, indentation.length() - 4); displaytext[numberlines] += "</"; displaytext[numberlines] += qualifiedname; displaytext[numberlines] += '>'; if(qualifiedname.equals(findnode)) displayboolean=false; Após ter encontrado o nó do final do elemento procurado, define-se displayboolean para false para as próximas buscas 25 XL XL, Java e DO 26 Encontrando Elementos pelo Nome (SAX) Ch17_03.java continuação... public void warning(saxparseexception exception) System.err.println("Warning: " + exception.getessage()); public void error(saxparseexception exception) System.err.println("Error: " + exception.getessage()); public void fatalerror(saxparseexception exception) System.err.println("Fatal error: " + exception.getessage()); Semelhante ao do exemplo anterior
XL APIs para anipulação de XL 27 Existem diversas API para a serialização de objetos Java como documentos XL Uma bastante interessante é a Simple XL Serialization: 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 XL que representam os objetos de uma aplicação. Para maiores informações: http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php XL Exercícios 28 Exercício cio 1: Compilar os programas, analisar o código e verificar a saída de cada um deles. Exercício cio 2: Escrever um programa Java que leia o documento XL 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ício cio 3: Escrever um programa Java que leia o documento XL ch16_01.xml e que apresente uma mensagem indicando quantos elementos do tipo senator existem no documento.