simple api for xml

26
Curso: XML, de los datos a la presentación Julio de 2005 CAPTIVA · www.captiva.es Simple API for XML

Upload: merton

Post on 16-Jan-2016

91 views

Category:

Documents


0 download

DESCRIPTION

XML. Simple API for XML. Introducción. ¿Cómo maneja la información representada en XML un programa? Requiere módulo parser  Lee fichero y crea representación en memoria (objetos, variables, …) ¿Qué alternativas tenemos? Podemos parsear “a pelo” el XML - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Simple API for XML

Curso: XML, de los datos a la presentaciónJulio de 2005

CAPTIVA · www.captiva.es

Simple API for XML

Page 2: Simple API for XML

Introducción

¿Cómo maneja la información representada en XML un programa? Requiere módulo parser Lee fichero y crea representación en memoria

(objetos, variables, …)

¿Qué alternativas tenemos? Podemos parsear “a pelo” el XML

Problemas Consideraciones UNICODE, substitución de ENTITIES, gestión

namespaces, …

Reinvención de la rueda

Utilizar parsers XML (xerces, saxon, msxml, etc.)

Existen dos tendencias principales Procesamiento en base a eventos

Procesamiento en árbol

Page 3: Simple API for XML

Procesamiento en base a eventos

El parser analiza el documento XML de forma secuencial

Puede pararse para insertar ENTIDADES de DTD o ir validando documento de acuerdo a

DTD/Schema

Según lee el documento va generando eventos.

Por ejemplo, consideremos este fragmento XML: <libro><titulo>Don Quijote de la Mancha</titulo><autor>Miguel de

Cervantes</autor></libro>

El parser podría generar los siguientes eventos:startElement:libro

startElement:titulo

content: Don Quijote de la Mancha

endElement:titulo

startElement:autor

content:Miguel de Cervantes

endElement:autor

endElement:libro

Page 4: Simple API for XML

Procesamiento en base a eventos (II)

Puede haber muchos eventos, no sólo apertura y cierre de un elemento Definición de un nuevo namespace, atributo encontrado, comentario, processing

instruction, etc.

Los parsers orientados a eventos no mantienen memoria del documento Sólo generan eventos usuario de la API debe mantener el estado si lo necesita

Parser sencillo Aplicación compleja

Limitaciones Edición y construcción de documentos

Recorrido aleatorio del documento p.e. al aplicar XPaths

Ventajas Simplicidad

Rapidez

Consumo de memoria reducido

Ideales para leer documentos que no cambian P.e. ficheros de configuración

Page 5: Simple API for XML

Procesamiento en base a modelo árbol

Los documentos XML describen estructuras en árbol

Representación en memoria de un árbol alternativa más lógica

Existen diferentes modelos de árbol para los documentos XML

ligeramente diferentes XPath

DOM (Document Object Model) API del W3C (Representación de

objetos en memoria)

XML Infoset también del W3C

Extensiones para aplicaciones particulares (SVG)

El más extendido y conocido DOM

Page 6: Simple API for XML

Procesamiento en base a modelo árbol (II)

Ventajas modelos de árbol El programa puede acceder de forma nativa a elementos XML

Objetos XML Objetos Java, objetos C++, estructuras C, etc.

No hay limitaciones en cuanto al recorrido Podemos volver hacia atrás, ir directamente al final, etc.

Sencillo modificar documento Se añaden nuevos objetos al árbol cuyas ramas se construyen típicamente en base a listas Modelo preferido para

editores XML, browsers

Inconvenientes Grandes requerimientos de memoria un documento XML en memoria puede ocupar. Varias veces

tamaño fichero XML. P.e. consideremos elemento: <a/> (4 bytes UTF-8)

Representación Java podría traducirse a objeto Element (Name(String),AttributeList,NamespaceList) Podría irse a

200 bytes

¿Cuánto ocuparía la representación de un fichero de 120 MB?

Inviable para procesamiento de grandes volúmenes de información Alternativas mixtas, trucos, etc.

Page 7: Simple API for XML

APIs de mayor nivel

Generalmente toda API de manejo información XML se basa por

debajo en modelo basado en árbol o basado en eventos

Incluso las implementaciones basadas en árbol se suelen crear

sobre APIs en base a eventos Es habitual que ofrezcan las dos posibilidades

Casos como las APIs de manejo de documentos SVG (Scalable

Vector Graphics) añaden extensiones propias a APIs DOM para

adaptarse mejor a sus características concretas

En la programación no tenemos por qué quedarnos con un único

modelo Es habitual combinar ambos.

Page 8: Simple API for XML

¿Qué es SAX? SAX significa Simple API for XML API basada en eventos

Web http://www.saxprojet.org

Originariamente fue una especificación para Java

Se ha convertido en un estándar de facto

Portada a multitud de plataformas. Existe soporte para SAX, aparte de Java en: MSXML 3.0 A través de objeto COM (Visual Basic, C, C++, …)

Pascal

Perl

Python 2.0

C (Xerces-C), C++

Xerces API Parser Java y otros lenguajes del proyecto Apache. Soporta entre otros Interfaces SAX version 2 (actual)

DOM level 3

JAXP 1.2 Java API for XML Processing

Validación XML Schema

Page 9: Simple API for XML

¿Cómo puedo utilizar SAX?

SAX es una API estándar

No obstante cada implementación puede variar ligeramente

Java es uno de los lenguajes más utilizados para la programación XML

Java proporciona la API JAXP Java API for XML Processing Proporciona interfaces comunes para utilizar: SAX, DOM y APIs para XSLT

Abstrae del fabricante.

Equivalente a JDBC o ADO (MS) para BBDD

¿Cómo uso entonces una API SAX en Java? Directamente a través del driver

A través de la API SAX independiente del driver

A través de la API JAXP

Page 10: Simple API for XML

¿Qué necesito para empezar?

Java 1.1 o superior Vamos a utilizar JDK 1.5

Un parser compatible SAX2 instalado en el classpath Usaremos Xerces http://xml.apache.org/xerces-j/

La distribución SAX2 para Java Viene integrado en JDK 1.5

Opcionalmente Entorno de desarrollo Java.

Usaremos NetBeans http://www.netbeans.org

Instalamos todos los componentes necesarios …

Page 11: Simple API for XML

Iniciando un proyecto

Abrimos Netbeans Creamos un nuevo proyecto web:

File New Project Escojemos el tipo: Java Application

Especificamos los datos del proyecto: Le damos un nombre al proyecto EjemploSAX Para Project Directory ponemos uno por ejemplo en

el Escritorio llamado CursoXML Podemos dejar MainClass vacío o le damos un

nombre EjemploSAX1

Page 12: Simple API for XML

Familiarización entorno Edición

Podemos navegar por el árbol de la izquierda por las fuentes y ficheros de configuración

Con el botón derecho podemos crear nuevas clases,ficheros jsp,… en el directorio indicado

Ejecución target principal del proyecto: Compila todas las fuentes no compiladas o modificadas y

empaqueta librerías en jars y crea fichero war Build Build Main Project El objetivo que ejecutaremos será jar

Construcción parcial: Si desplegamos el fichero “makefile” del proyecto de ant

(build.xml) dentro src y pulsamos con el botón derecho podemos ejecutar cada target por separado (compilación, javadoc, etc.).

Page 13: Simple API for XML

Creando la aplicación Creamos un paquete: p.e. es.captiva.cursoxml Creamos una clase que se extienda de org.xml.sax.helpers.DefaultHandler:

import org.xml.sax.helpers.DefaultHandler;import org.xml.sax.helpers.XMLReaderFactory;import org.xml.sax.XMLReader;

public class EjemploSAX1 extends DefaultHandler{ public EjemploSAX1 (){ super(); }}

Le añadimos un método main que va a instanciar un lector (XMLReader) a partir de una factoría XMLReaderFactory .

public static void main (String args[]) {

XMLReader xr = XMLReaderFactory.createXMLReader(); }

Page 14: Simple API for XML

Creando la aplicación (II)

La clase XMLReaderFactory es una clase factoría que busca la implementación de parser adecuado.

¿Cómo determina la fábrica qué parser debe escoger? Variable de entorno: org.xml.sax.driver ¿Cómo le asignamos un valor?

Desde la llamada al programajava -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser EjemploSAX1

sample.xml

Desde dentro del programaSystem.setProperty("org.xml.sax.driver",

"org.apache.xerces.parsers.SAXParser"); También podríamos en su lugar crear una instancia del driver

directamente Perderíamos flexibilidadXMLReader xr = new org.apache.xerces.parsers.SAXParser();

Page 15: Simple API for XML

Asociación gestor eventos

Una vez que disponemos de un lector necesitamos asociarle el handler, que es la clase que recibirá los eventos.

Utilizamos los métodos setContentHandler() Para asociar clase que recibe los

eventos relacionados con lectura del documento (encontrado apertura elemento, etc.)

setErrorHandler() Para asociar los eventos de error en el documento

¿Qué ocurre si hay un evento de un tipo y no hay un handler asociado?

Se ignora el evento Podría ocurrir un error y que el driver acabara sin decir nada.

Page 16: Simple API for XML

Asociación gestor eventos (II)

En nuestra aplicación el gestor de eventos es la propia clase (EjemploSAX1):

public static void main (String args[]){XMLReader xr = XMLReaderFactory.createXMLReader();EjemploSAX1 handler = new EjemploSAX1();xr.setContentHandler(handler);xr.setErrorHandler(handler);

}

Sólo queda invocar al parser, que hay que alimentarlo con datos XML. El parser recibe estos datos en una clase org.xml.sax.InputSource.

Si miramos la documentación de la API (doc en Xerces) vemos que un InputSource puede crearse a partir de un InputStream o Reader, más adecuado para leer contenido textual.

Page 17: Simple API for XML

Alimentando al parser ¿Cómo va a recibir los datos nuestra aplicación?

Indicando nombres de ficheros XML en línea de comandos. Creamos un java.io.FileReader (subclase de

Reader para ficheros) por cada fichero de entrada.for (int i = 0; i < args.length; i++) { System.out.println(“Procesando fichero “ +

args[i] + “...”); FileReader fr = new FileReader(args[i]); xr.parse(new InputSource(fr));}

El método parse() es el que llama al parser y empieza a procesador documentos XML.

Page 18: Simple API for XML

Gestión de eventos

Esta aplicación por ahora no hace nada Necesitamos gestionar los eventos

Escribir métodos dentro de nuestra clase que reciben eventos.

Métodos: startDocument() endDocument() startElement(String uri, String name, String

qName, Attributes atts) endElement(String uri, String name, String

qName) characters (char ch[], int start, int

length) Otros métodos Ver API DefaultHandler

Page 19: Simple API for XML

Gestión de eventos (II) Nuestra aplicación va a:

Contar el número de nodos elemento Imprimir inicio y cierre de elemento Imprimir texto dentro de los elementos

Para el contador implementamos variable miembro de EjemploSAX1: int numElementos;

Implementamos la función miembro llamada al inicio del documento dentro de :public void startDocument (){ this.numElementos = 0;

System.out.println("********** Inicio del documento **********");}

Y la de fin de documento, donde imprimimos el número de elementos encontrados:

public void endDocument (){

System.out.println("************ Fin del documento ***********");System.out.println(">>>>>>> Se han procesado: " + this.numElementos + " elementos");

}

Page 20: Simple API for XML

Gestión de eventos (III) Al comenzar un elemento imprimimos su nombre e incrementamos el contador:

public void startElement (String uri, String name, String qName, Attributes atts)

{ this.numElementos ++;

if (uri.length() == 0) System.out.println(“Inicio elemento: " + qName);else System.out.println(“Inicio elemento: {" + uri + "}" + name);

} Cabe destacar el parámetro uri. En caso de tratarse de un elemento definido en un

namespace el parser pasa la URI de dicho namespace. El parámetro qName es la versión cualificada del nombre del elemento P.e.:

xhtml:body Y evento para fin del elemento:

public void endElement(String uri, String name,String qName) { if (uri.length() == 0) System.out.println("Fin elemento: " + qName); else System.out.println("Fin elemento: {" + uri + "}" + name);}

Page 21: Simple API for XML

Gestión de eventos (IV) Por último el evento de texto. Para que se vea más claro substituimos tabuladores y nuevas lineas por “\t”, “\

n”, “\r”:public void characters (char ch[], int start, int length){

System.out.print(“Texto: \"");for (int i = start; i < start + length; 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");

}

Page 22: Simple API for XML

Últimos retoques Completamos la importación de todos las clases que

necesitamos para que no se queje el compilador:package es.captiva.xml.ejemplos;

import java.io.FileReader;

import org.xml.sax.helpers.DefaultHandler;import org.xml.sax.helpers.XMLReaderFactory;import org.xml.sax.XMLReader;import org.xml.sax.InputSource;import org.xml.sax.Attributes;

Compilamos el proyecto y obtenemos EjemploSAX1.jar en el directorio dist

Page 23: Simple API for XML

Ejecución

Copiamos EjemploSAX1.jar a un directorio con ficheros XML (cualquiera de prácticas pasadas) y ejecutamos:java –jar EjemploSAX1.jar fich1.xml

fich2.xml fich3.xml

Vemos la salida del programa. Funciona y no debería. ¿Por qué?

No hemos especificado ningún driver La explicación JDK incluye un driver que utiliza

por defecto

Page 24: Simple API for XML

Ejecución (II)

Volvemos a ejecutar especificando el driver de Xerces:java –Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser –jar EjemploSAX1.jar

fich1.xml fich2.xml fich3.xml

Ahora obtenemos el error:Exception in thread "main" java.lang.ClassNotFoundException:

org.apache.xerces.parsers.SAXParser at org.xml.sax.helpers.XMLReaderFactory.loadClass(XMLReaderFactory.java:189)at org.xml.sax.helpers.XMLReaderFactory.createXMLReader(XMLReaderFactory.java:150)at es.captiva.xml.ejemplos.EjemploSAX1.main(EjemploSAX1.java:88)

No ha encontrado la clase del driver especificada. Copiamos xercesImpl.jar a %JAVA_HOME%\jre\lib\ext

Page 25: Simple API for XML

Ejercicio

Probar con los ficheros XML de prácticas anteriores

Buscar ficheros con y sin namespaces Modificaciones ejercicio

Añadir soporte para atributos (número de atributos totales e impresión de los que encuentre)

Añadir soporte para NOTATIONS y PROCESSING INSTRUCTIONS

Page 26: Simple API for XML

Referencias

SAX http://http://www.saxproject.org

Xerces http://xml.apache.org/xerces-j/

Javadoc API XML http://java.sun.com/xml/jaxp/dist/1.1/docs/ap

i/