Está en la página 1de 72

Apuntes de XML

Autor: Diego Arranz Hernando

Introduccin o Motivacin HTML y XML Para qu sirve XML? Principales usos o Terminologa o Cuadro del XML y alcance del curso Creacin de documentos XML o Sintaxis Un ejemplo completo Reglas bsicas Otras construcciones Espacios de nombres Cabecera Terminologa o Reglas de diseo Restringir documentos XML o Por qu restringir los datos? o DTD's Un ejemplo de DTD Elementos Atributos Declaracin DOCTYPE Entidades o Esquemas XML Esquemas XML vs DTDs Un primer ejemplo Caractersticas Espacios de nombres Uso desde un documento Ms estructuras Tipos Atributos Importar esquemas Un ejemplo completo Otras formas de construir esquemas XML Presentacin y transformacin de documentos XML o Hojas de estilo CSS CSS con XML Un ejemplo o Lenguaje XSLT Introduccin a XSLT Ventajas y desventajas Formas de uso Un ejemplo de hoja Caractersticas XPath Crear elementos Ordenaciones Manipulacin de XML desde programas Java o Analizar XML con SAX Introduccin a SAX El analizador SAX Un primer ejemplo El manejador de contenido

Los mtodos del manejador Cdigo portable Validacin Otro ejemplo o Manipular XML con DOM Introduccin a DOM El analizador DOM Un primer ejemplo Manipulacin del rbol Cdigo portable Otro ejemplo Ms formas de manipular el rbol Crear documentos Imprimir documentos Un ejemplo Modificar documentos XML y las bases de datos o Generar XML a partir de consultas o Transferir datos desde documentos XML o Herramientas o XML como almacn de datos Otros temas de inters o XLink o JDOM Otra API ms Ventajas y desventajas Una API en desarrollo o Marcos de publicacin web El problema Soluciones con tecnologa conocida Contenido y presentacin La solucin: marcos de publicacin web Ventajas Un ejemplo de marco de publicacin: Cocoon Servicios web o Introduccin o Terminologa Tecnologas estndar APIs Java o JAXR Registros Introduccin a JAXR Un cliente JAXR o JAXM Mensajes SOAP Introduccin a JAXM Ejemplos o JAX-RPC Introduccin Un ejemplo Bibliografa recomendada o En ingls o En castellano Enlaces recomendados o Generales o Introduccin o Creacin de documentos XML o Restriccin de documentos XML

Presentacin y transformacin de documentos XML Manipulacin de XML desde programas Java XML y las bases de datos Otros temas de inters Servicios web Material utilizado o Bibliografa o Enlaces o Herramientas Ejercicios o Creacin de documentos XML Enunciado Solucin o DTDs Enunciado Solucin o Esquemas XML Enunciado Solucin o XSLT Enunciado Solucin o SAX Enunciado Solucin o DOM Enunciado Solucin o DOM (otro) Enunciado Solucin

o o o o o

Apuntes de XML
Autor: Diego Arranz Hernando

Introduccin o Motivacin HTML y XML Para qu sirve XML? Principales usos o Terminologa o Cuadro del XML y alcance del curso

Introduccin
Motivacin
HTML y XML
Una buena forma de entender en un primer vistazo qu es el lenguaje XML es compararlo con el sobradamente conocido lenguaje HTML. Veamos primero un trozo de cdigo HTML:
<h1> Comedor </h1> <ul> <li> <b>Mesa redonda de madera de arce</b>. El fabricante es <i>Muebles Albacete</i> y su precio 40000. </li> <li> <b>Dos sillas de madera de arce</b>, de excelente calidad, con un coj&iacute;n azul cada una. </li> <li> <b>3 sillas de madera de roble</b>. </li> </ul>

Y ahora un trozo de cdigo XML equivalente:


<comedor> <mesa tipo="redonda" madera="arce"> <fabricante>Muebles Albacete</fabricante> <precio>40000</precio> </mesa> <silla madera="arce"> <cantidad>2</cantidad> <calidad>excelente</calidad> <cojin incluido="s"> <color>azul</color> </cojin> </silla> <silla madera="roble"> <cantidad>3</cantidad> <calidad>normal</calidad> </silla> </comedor>

Lo fundamental: o HTML: orientado a la presentacin de datos.

XML: orientado a los datos en s mismos. La principal ventaja de XML es que cualquier programa informtico trabajar mejor con datos en XML. HTML es un lenguaje de presentacin. Define un conjunto de etiquetas y atributos vlidos, una utilizacin vlida de estos elementos y un significado visual para cada elemento del lenguaje. XML no define las etiquetas ni cmo se utilizan, slo define unas pocas reglas sintcticas para crear documentos. Por eso XML es un metalenguaje (un lenguaje para definir otros lenguajes). Sustituye XML a HTML? No, pues sirven para cosas distintas: HTML para presentar informacin en pginas web y XML para representar e intercambiar datos, independientemente de su presentacin. XML y HTML son complementarios.

o o

Para qu sirve XML? Principales usos

XML aplicado a los sitios web: permite separar contenido y presentacin, y que los mismos datos se puedan mostrar de varias formas distintas sin demasiado esfuerzo. XML para la comunicacin entre aplicaciones: representacin de los datos muy simple, fcil de transmitir por la red, estndar. En los ltimos tiempos este uso se est haciendo muy popular con el surgimiento de los Servicios web. XML para la configuracin de programas: representacin de los datos simple y estndar, en contraposicin con los crpticos formatos propietarios.

Terminologa

XML: Es slo el metalenguaje sobre el que se construye todo. Por s mismo tiene un valor limitado. Cuando se habla de XML, normalmente no se refiere slo al lenguaje XML, sino tambin a todos los lenguajes y herramientas relacionadas. DTD: Lenguaje para establecer restricciones en los documentos XML. Esquema XML: Otro lenguaje para restringir los documentos XML, que soluciona diversos problemas de las DTDs. XSLT: Lenguaje para transformar documentos de un formato XML a otro formato (HTML, otro vocabulario XML, texto plano, PDF, etc.) SAX: API que permite recorrer secuencialmente un documento XML, y responder a una serie de eventos. DOM: API que proporciona una representacin de los documentos XML en forma de rbol, permitiendo el recorrido y manipulacin de los datos. XHTML: Reformulacin del HTML como formato de datos XML. SOAP: Lenguaje que especifica la forma de enviar contenido XML a travs de Internet. XML-RPC: Mecanismo para invocacin remota de procedimientos (mtodos) utilizando XML como forma de comunicacin. Servicios web: Aplicaciones que se publican en la web y pueden ser accedidas de forma estndar desde cualquier lugar de Internet.

Cuadro del XML y alcance del curso



Ncleo: Se tratar en detalle el lenguaje XML. Se vern los aspectos ms importantes de los lenguajes DTD, esquemas XML y XSLT. Se introducir XLink. APIs Bsicas: Se ver en detalle cmo trabajar con SAX y DOM, utilizando como lenguaje Java. Servicios web: Se explicar el por qu de su importancia y se detallarn las tecnologas asociadas con ellos. APIs para servicios web: Se realizar una introduccin a una serie de APIs para trabajar con servicios web desde Java (JAXR, JAXM, JAX-RPC). Otras aplicaciones y tecnologas: Se vern por encima algunos otros temas relacionados con XML: o Aplicacin de hojas CSS a documentos XML o Relacin de XML con las bases de datos o Alternativa a la API DOM para Java: JDOM o Marcos de publicacin web Al final de este documento se recoge una bibliografa recomendada y numerosos enlaces de Internet para poder profundizar en cualquiera de los temas tratados en el curso.

Apuntes de XML
Autor: Diego Arranz Hernando

Creacin de documentos XML o Sintaxis Un ejemplo completo Reglas bsicas Otras construcciones Espacios de nombres Cabecera Terminologa o Reglas de diseo

Creacin de documentos XML


Sintaxis
Un ejemplo completo
Ejemplo completo de documento XML:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <?xml-stylesheet href="librohtml.xsl" type="text/xsl"?> <?xml-stylesheet href="librowml.xsl" type="text/xsl" media="wap"?> <?cocoon-process type="xslt"?> <!-- Referencia la DTD --> <!DOCTYPE Libro SYSTEM "libro.dtd"> <!-- Comienza el contenido --> <Libro xmlns="http://www.mislibros.com/libros/javaxml" xmlns:Catalogo="http://www.mislibros.com/catalogo"> <Titulo>Java y XML</Titulo> <Catalogo:Seccion>Programacin</Catalogo:Seccion> <Catalogo:SubSeccion>XML</Catalogo:SubSeccion> <Contenido> <Capitulo materia="XML"> <Tema>Introduccin</Tema> <subcapitulo1 apartados="7">Qu es</subcapitulo1> <subcapitulo1 apartados="3">Cmo se usa</subcapitulo1> </Capitulo> <Capitulo materia="XML"> <Tema>Creando XML</Tema> <subcapitulo1 apartados="0">Un documento XML</subcapitulo1> <subcapitulo1 apartados="2">La cabecera</subcapitulo1> <subcapitulo1 apartados="6">El contenido</subcapitulo1> </Capitulo> <Capitulo materia="Java"> <Tema>Analizando XML</Tema> <subcapitulo1 apartados="3">Preparacin</subcapitulo1> <subcapitulo1 apartados="3" dificil="si">SAX</subcapitulo1> <subcapitulo1 apartados="9" dificil="si">Manejadores</subcapitulo1> <subcapitulo1 apartados="0">Una forma mejor de cargar el analizador</subcapitulo1> </Capitulo> <Separacion/> <Capitulo materia="Java">

<Tema>JDOM</Tema> <subcapitulo1 apartados="2">Introduccin</subcapitulo1> <subcapitulo1 apartados="4" dificil="si">DOM&amp;JDOM</subcapitulo1> </Capitulo> </Contenido> <Compra> <![CDATA[ <Paso 1>Encontrar una librera. <Paso 2>Encontrar el libro. <Paso 3>Comprar el libro. ]]> </Compra> <Copyright>&OReillyCopyright;</Copyright> </Libro>

Reglas bsicas

Hay dos tipos de construcciones: el marcado (entre <...> &...; ) y los datos de carcter (todo lo dems). Todo documento XML se compone de elementos. Cada elemento est delimitado por una etiqueta de comienzo y otra de fin, a no ser que sea vaco. Los elementos vacos constan de una nica etiqueta. Los nombres de las etiquetas son arbitrarios y no pueden contener espacios. Siempre hay un elemento raz, cuya etiqueta de inicio ha de ser la primera de todas y la de cierre la ltima de todas. Cada elemento puede contener datos de carcter, elementos, ambas cosas a la vez o puede estar vaco. No se puede mezclar la anidacin de las etiquetas: los elementos deben abrirse y cerrarse por orden. Los elementos pueden tener atributos (propiedades) que nos ofrecen informacin sobre ellos. Los valores de los atributos deben ir entrecomillados. Tanto atributos como valores son arbitrarios. Maysculas y minsculas no son intercambiables. El espacio en blanco es libre, se puede utilizar para leer mejor el documento.

Otras construcciones

Se pueden utilizar comentarios, que el analizador no tratar, en cualquier sitio excepto dentro de las declaraciones, etiquetas y otros comentarios. Las secciones CDATA sirven para introducir texto que el analizador tendr en cuenta como datos de carcter, sin interpretarlo como XML. Las entidades predefinidas permiten incluir ciertos caracteres sin que sean tomados como XML: o &amp; para el & o &lt; para el < o &gt; para el > o &apos; para el ' o &quot; para el " Podemos definir nuestras propias entidades, lo veremos con las DTDs.

Espacios de nombres

Los espacios de nombres sirven para evitar las colisiones entre elementos del mismo nombre, y en general, para distinguir los distintos grupos de elementos en un mismo documento. Cada espacio de nombres se asocia con una URL, que slo sirve como identificador nico y no tiene por qu ser vlida.

Cabecera

La cabecera, que es opcional aunque recomendable, da informacin sobre cmo manejar el documento a los analizadores y otras aplicaciones. Puede contener: o Una declaracin XML para el analizador, con la versin, juego de caracteres utilizado, y una indicacin de si el documento es o no autnomo (si requiere o no otros documentos). o Instrucciones de proceso para otras aplicaciones. o Una declaracin DOCTYPE, que referencia a la DTD que restringe el documento.

Terminologa

Cuando un documento cumple con las reglas sintcticas que hemos descrito, se le denomina documento bien formado. Un documento vlido, adems de ser bien formado, cumple las restricciones que le impone una DTD o un esquema XML.

Reglas de diseo

El diseo de la estructura de un documento XML no es una tarea trivial. Depende de un buen anlisis del problema concreto a resolver (cmo se va a utilizar el documento), lo cual queda fuera del alcance de este curso. No obstante, se ofrecen a continuacin algunas reglas prcticas. Siempre que sea posible, usar una DTD o esquema existente. Nos ahorramos disear los documentos XML y posibilita el intercambio de datos con otros que utilicen la DTD o esquema. La principal decisin es utilizar para los datos de los elementos subelementos o atributos. Por ejemplo:

<diapositiva> <ttulo>Aqu el ttulo...</ttulo> </diapositiva> <diapositiva ttulo="Aqu el ttulo..."> ... </diapositiva>

Hay una serie de criterios: o Si el dato contiene subestructuras: elemento. o Si el dato es de gran tamao: elemento. o Si el dato cambia frecuentemente: elemento. o Si el dato es de pequeo tamao, y raramente cambia: normalmente, atributo. o Si el dato slo puede tener unos cuantos valores fijos: atributo. o Si el dato se va a mostrar a un usuario o aplicacin: elemento. Si el dato gua el procesamiento del XML pero no se va a mostrar: atributo.

Apuntes de XML
Autor: Diego Arranz Hernando

Restringir documentos XML o Por qu restringir los datos? o DTD's Un ejemplo de DTD Elementos Atributos Declaracin DOCTYPE Entidades o Esquemas XML Esquemas XML vs DTDs Un primer ejemplo Caractersticas Espacios de nombres Uso desde un documento Ms estructuras Tipos Atributos Importar esquemas Un ejemplo completo Otras formas de construir esquemas XML

Restringir documentos XML


Por qu restringir los datos?

La primera razn es que podemos realizar comprobaciones estrictas sobre los datos, para asegurarnos de que tienen un formato vlido de acuerdo a lo que queremos. Otra razn es la documentacin: no siempre estar claro para cualquier persona el significado de un determinado documento XML:

<?xml version="1.0"?> <pagina> <pantalla> <nombre>Compras</nombre> <color>#CC9900</color> <fuente>Arial</fuente> </pantalla> <contenido> <p>Aqui un monton de contenido</p> </contenido> </pagina> <?xml version="1.0"?> <pagina> <pantalla> <nombre>Compras</nombre> <color>#CC9900</color> <fuente>Arial</fuente> </pantalla> <pantalla> <nombre>Mensajes</nombre> <color>#9900FF</color> <fuente>Arial</fuente> </pantalla> <pantalla>

<nombre>Noticias</nombre> <color>#EECCEE</color> <fuente>Helvetica</fuente> </pantalla> <contenido> <p>Aqui un monton de contenido</p> </contenido> </pagina>

Viendo el primer ejemplo podemos pensar en que describe informacin de una pantalla para determinado cliente. Viendo el segundo, la interpretacin cambia. En realidad, son varios enlaces a las pantallas disponibles. Las DTDs y los esquemas XML aclaran situaciones de este tipo. Otra ventaja de los mecanismos de restriccin es que no hay que cambiar el cdigo de las aplicaciones si las restricciones cambian (slo las DTDs o esquemas que sean). Como desventaja, la validacin supone tiempo adicional de proceso. Una solucin posible para algunos sistemas es validar en la fase de desarrollo y pruebas y quitar la validacin al implantar el sistema.

DTD's
Un ejemplo de DTD

Para utilizar una DTD como mecanismo de restriccin, se especifica lo siguiente en el documento XML:
<!DOCTYPE Libro SYSTEM "libro.dtd">

DTD para el ejemplo del libro:


<!ELEMENT Libro (Titulo, Catalogo:Seccion, Catalogo:SubSeccion, Contenido, Compra, Copyright)> <!ATTLIST Libro xmlns CDATA #REQUIRED xmlns:Catalogo CDATA #REQUIRED > <!ELEMENT Titulo (#PCDATA)> <!ELEMENT Catalogo:Seccion (#PCDATA)> <!ELEMENT Catalogo:SubSeccion (#PCDATA)> <!ELEMENT Contenido ((Capitulo+)|(Capitulo+, Separacion?)+)> <!ELEMENT Capitulo (Tema, Seccion+)> <!ATTLIST Capitulo materia (XML|Java) "Java" > <!ELEMENT Tema (#PCDATA)> <!ELEMENT Seccion (#PCDATA)> <!ATTLIST Seccion apartados CDATA #REQUIRED dificil (si|no) "no" > <!ELEMENT Separacion EMPTY> <!ELEMENT Compra (#PCDATA)> <!ELEMENT Copyright (#PCDATA)> <!ENTITY OReillyCopyright SYSTEM "copyright.txt">

Elementos

Los elementos permitidos se especifican con ELEMENT, seguido del nombre y el tipo del elemento. Los elementos que se pueden anidar dentro de otros se especifican entre parntesis y separados por comas. Importa el orden. El tipo menos restrictivo es ANY, que permite cualquier contenido para un elemento. Para datos de tipo texto, se usa #PCDATA.

Para elementos vacos, EMPTY. Modificadores de nmero de ocurrencias: o ?: Una vez o ninguna o +: Al menos una vez o *: Cualquier nmero de veces o ninguna o (nada): Exactamente una vez Para opciones alternativas: separar con |.

Atributos

Los atributos permitidos para un elemento se especifican con ATTLIST y el nombre del elemento seguido de los nombres de los atributos, con un tipo y modificador obligatorios. El tipo del atributo puede ser CDATA para cualquier valor, o una enumeracin de los valores permitidos. Otros posibles tipos son: o NMTOKEN para restringir el valor a un nombre XML vlido (es decir, que empiece con una letra o guin de subrayado y contenga slo letras, nmeros, guiones de subrayado, guiones y puntos, sin espacios) o ID, adems de las restricciones que impone NMTOKEN, impone que el valor sea nico en todo el documento. El modificador puede ser #REQUIRED para atributos obligatorios, #IMPLIED para opcionales, o #FIXED valor_fijo para valores fijos. Tambin puede ser un valor por defecto.

Declaracin DOCTYPE

SYSTEM sirve para DTDs "personales". Se puede espicificar un fichero local o un fichero

accesible a travs de una URL. Se puede especificar una DTD pblica con PUBLIC, en la que queda reflejado el propietario de la misma, una descripcin y el idioma.
<!DOCTYPE elem_raiz PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Es posible incrustar la DTD internamente en el documento XML:


<!DOCTYPE elem_raiz [ ... ]>

Incluso es posible tener una DTD interna y otra externa. En caso de conflictos, prevalece siempre la interna.

Entidades

En la DTD tambin se especifica cmo resolver las entidades generales, con ENTITY. Se puede especificar: o Directamente el contenido entre comillas. o El contenido de un fichero con SYSTEM. En el documento XML se invocan con &...; Tambin son tiles las entidades paramtricas, que a diferencia de las generales se utilizan ms adelante en la misma DTD en que se definen. Se invocan con %...;
<!ENTITY % Shape "(rect|circle|poly|default)">

Esquemas XML
Esquemas XML vs DTDs

Ventajas sobre las DTDs:

Restricciones ms precisas sobre los documentos XML (tanto en estructura como en tipos de datos). o Son documentos XML, por lo que la sintaxis es familiar y las herramientas los pueden manejar sin tcnicas especiales (no como las DTDs). o Soporte para espacios de nombres. o Permiten definir elementos globales y locales (las DTDs slo globales). Desventajas sobre las DTDs: o Ms complejos. Esto causa: Dificultades en su comprensin por humanos, sobre todo si estn acostumbrados a las DTDs. Herramientas ms grandes y lentas. o Muchas aplicaciones funcionan ya sobre DTDs existentes (la conversin es posible pero llevar un tiempo). o Se trata de una especificacin muy reciente, por lo que el soporte por parte de muchas herramientas an est en proceso.

Un primer ejemplo
Pasemos a esquema XML esta sencilla DTD:
<!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT Libreria (Libro)+> Libro (Titulo, Autor+, Fecha, ISBN)> Titulo (#PCDATA)> Autor (#PCDATA)> Fecha (#PCDATA)> ISBN (#PCDATA)>

Un esquema XML equivalente:


<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.libros.org" xmlns="http://www.libros.org" elementFormDefault="qualified"> <xs:element name="Libreria" type="TipoLibreria"/> <xs:complexType name="TipoLibreria"> <xs:sequence> <xs:element name="Libro" type="TipoLibro" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="TipoLibro"> <xs:sequence> <xs:element name="Titulo" type="xs:string"/> <xs:element name="Autor" type="xs:string" maxOccurs="3"/> <xs:element name="Fecha" type="xs:string"/> <xs:element name="ISBN" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>

Caractersticas

Observar que, a diferencia de la DTD, es XML. Observar cmo los elementos ms generales referencian a los ms concretos, hasta llegar a los ms bsicos. No es la nica forma de hacerlo. minOccurs y maxOccurs por defecto valen 1. Observar cmo definimos los elementos bsicos como de tipo string. Los elementos vacos se definen con un complexType sin elementos.

Espacios de nombres

Hay mltiples espacios de nombres involucrados en un esquema: o Para los elementos del propio esquema (xmlns:xs).

Para los elementos a restringir (targetNamespace). Para los elementos referenciados con el atributo ref (xmlns), se ver un ejemplo al final. El atributo elementFormDefault sirve para exigir que al usar el esquema desde un documento los elementos se asocien con el targetNamespace del esquema.

o o

Uso desde un documento


Este es un pequeo documento XML que utiliza el esquema:
<?xml version="1.0"?> <Libreria xmlns="http://www.libros.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.libros.org libreria.xsd"> <Libro> <Titulo>My Life and Times</Titulo> <Autor>Paul McCartney</Autor> <Autor>Phil McCartney</Autor> <Fecha>July, 1998</Fecha> <ISBN>94303-12021-43892</ISBN> </Libro> ... </Libreria>

Ms estructuras


Tipos

Otras posibilidades de estructura, adems de sequence: o choice: Para alternativas. o all: Para conjuntos de elementos en los que no importa el orden. Las tres estructuras pueden tener maxOccurs (en all el mximo es 1) y minOccurs

En un esquema XML se pueden utilizar tipos para los elementos y atributos, de forma similar a cualquier lenguaje de programacin. Existen una serie de tipos predefinidos, algunos ejemplos: o string o boolean (true-false) o integer o positiveInteger (desde 1) o decimal (7.08) o time (hh:mm:ss) o date (YYYY-MM-DD) o anyURI (http://www.web.com) o ID y NMTOKEN (ver DTDs) Es posible crear nuevos tipos de datos a partir de los existentes, imponiendo restricciones a stos:

<xs:simpleType name="TipoColores"> <xs:restriction base="xs:string"> <xs:enumeration value="rojo"/> <xs:enumeration value="blanco"/> <xs:enumeration value="azul"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="TipoEdad"> <xs:restriction base="xs:integer"> <xs:minInclusive value="18"/> <xs:maxInclusive value="65"/> </xs:restriction> </xs:simpleType>

enumeration, minInclusive y maxInclusive son algunos ejemplos de facetas, hay muchas

ms.

Atributos
Veamos cmo se tratan los atributos de los elementos. Dado el siguiente fragmento de DTD:
<!ELEMENT Libro (Titulo, Autor+, Fecha, ISBN)> <!ATTLIST Libro Categoria (biografia | ensayo | ficcion) #REQUIRED Disponible (true | false) "false" Corrector CDATA "" >

Resulta el siguiente fragmento de esquema XML:


<xs:complexType name="TipoLibro"> <xs:sequence> <xs:element name="Titulo" type="xs:string"/> <xs:element name="Autor" type="xs:string" maxOccurs="3"/> <xs:element name="Fecha" type="xs:string"/> <xs:element name="ISBN" type="xs:string"/> </xs:sequence> <xs:attribute name="categoria" type="TipoCat" use="required"/> <xs:attribute name="disponible" type="xs:boolean" default="false"/> <xs:attribute name="corrector" type="xs:string" default=""/> </xs:complexType> <xs:simpleType name="TipoCat"> <xs:restriction base="xs:string"> <xs:enumeration value="biografia"/> <xs:enumeration value="ensayo"/> <xs:enumeration value="ficcion"/> </xs:restriction> </xs:simpleType>

Si un elemento tiene contenido simple y atributos (por ejemplo: <elem atr=h4>678</elem>), se restringe as:
<xs:element name="elem"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:integer"> <xs:attribute name="atr" type="xs:string" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element>

Importar esquemas

Cuando se deben restringir varios espacios de nombre, cada espacio se restringe en un esquema, y desde el principal se importan los dems:
<xs:import schemaLocation="------.xsd"/>

Un ejemplo completo
Para terminar, un ejemplo completo de un esquema XML:
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.miempresa.org/pedidos" xmlns="http://www.miempresa.org/pedidos" elementFormDefault="qualified">

<xs:element name="Pedido" type="TipoPedido"/> <xs:complexType name="TipoPedido"> <xs:sequence> <xs:element name="Destino" type="TipoDireccion"/> <xs:element name="Ordenante" type="TipoDireccion"/> <xs:element name="Observaciones" type="xs:string" minOccurs="0"/> <xs:element name="Contenido" type="TipoContenido"/> </xs:sequence> <xs:attribute name="fecha" type="xs:date" use="required"/> </xs:complexType> <xs:complexType name="TipoDireccion"> <xs:sequence> <xs:element name="Nombre" type="xs:string"/> <xs:element name="Direccion" type="xs:string"/> <xs:element name="Ciudad" type="xs:string"/> <xs:element name="CodPostal" type="TipoCodPostal"/> </xs:sequence> </xs:complexType> <xs:simpleType name="TipoCodPostal"> <xs:restriction base="xs:positiveInteger"> <xs:minInclusive value="1000"/> <xs:maxInclusive value="60000"/> </xs:restriction> </xs:simpleType> <xs:complexType name="TipoContenido"> <xs:sequence> <xs:element name="Producto" type="TipoProducto" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="TipoProducto"> <xs:sequence> <xs:element name="Nombre" type="xs:string"/> <xs:element name="Cantidad" type="TipoCantidad"/> <xs:element name="Precio" type="xs:decimal"/> <xs:element name="Observaciones" type="xs:string" minOccurs="0"/> </xs:sequence> <xs:attribute name="codigo" type="TipoCodigo" use="required"/> </xs:complexType> <xs:simpleType name="TipoCantidad"> <xs:restriction base="xs:positiveInteger"> <xs:maxExclusive value="100"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="TipoCodigo"> <xs:restriction base="xs:string"> <xs:pattern value="\d{3}-[A-Z]{2}"/> </xs:restriction> </xs:simpleType> </xs:schema>

Y un documento que lo utiliza:


<?xml version="1.0" encoding="ISO-8859-1"?> <Pedido xmlns="http://www.miempresa.org/pedidos" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.miempresa.org/pedidos pedido.xsd" fecha="1999-10-20"> <Destino> <Nombre>Alicia Abad</Nombre> <Direccion>Plaza de la Duquesa 12</Direccion> <Ciudad>Albacete</Ciudad> <CodPostal>05020</CodPostal>

</Destino> <Ordenante> <Nombre>Roberto Movilla</Nombre> <Direccion>General Ricardos 56</Direccion> <Ciudad>Madrid</Ciudad> <CodPostal>28055</CodPostal> </Ordenante> <Observaciones>Es urgente, mi cesped est muy alto</Observaciones> <Contenido> <Producto codigo="872-AA"> <Nombre>Cortadora de cesped</Nombre> <Cantidad>1</Cantidad> <Precio>148.95</Precio> <Observaciones>Confirmar que es elctrica</Observaciones> </Producto> <Producto codigo="926-FH"> <Nombre>Taladradora</Nombre> <Cantidad>3</Cantidad> <Precio>10.98</Precio> </Producto> </Contenido> </Pedido>

Otras formas de construir esquemas XML


Anidando los elementos:
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.libros.org" xmlns="http://www.libros.org"> <xsd:element name="Libreria"> <xsd:complexType> <xsd:sequence> <xsd:element name="Libro" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="Titulo" type="xsd:string"/> <xsd:element name="Autor" type="xsd:string"/> <xsd:element name="Fecha" type="xsd:string"/> <xsd:element name="ISBN" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>

Referenciando a los elementos:


<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.libros.org" xmlns="http://www.libros.org"> <xs:element name="Libreria"> <xs:complexType> <xs:sequence> <xs:element ref="Libro" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Libro"> <xs:complexType> <xs:sequence> <xs:element ref="Titulo" minOccurs="1" maxOccurs="1"/> <xs:element ref="Autor" minOccurs="1" maxOccurs="unbounded"/> <xs:element ref="Fecha" minOccurs="1" maxOccurs="1"/> <xs:element ref="ISBN" minOccurs="1" maxOccurs="1"/> </xs:sequence>

</xs:complexType> </xs:element> <xs:element name="Titulo" type="xs:string"/> <xs:element name="Autor" type="xs:string"/> <xs:element name="Fecha" type="xs:string"/> <xs:element name="ISBN" type="xs:string"/> </xs:schema>

En ambos casos se utilizan tipos complejos annimos (sin nombre). Se puede hacer lo mismo con los tipos simples.

Apuntes de XML
Autor: Diego Arranz Hernando

Presentacin y transformacin de documentos XML o Hojas de estilo CSS CSS con XML Un ejemplo o Lenguaje XSLT Introduccin a XSLT Ventajas y desventajas Formas de uso Un ejemplo de hoja Caractersticas XPath Crear elementos Ordenaciones

Presentacin y transformacin de documentos XML


Hojas de estilo CSS
CSS con XML

CSS es un lenguaje de hojas de estilo que se utiliza normalmente para controlar la presentacin de documentos HTML, pero tambin se puede utilizar con documentos XML. Su principal caracterstica, en contraste con el lenguaje XSLT, es su sencillez. Ventajas: o Fcil de aprender y utilizar. Muchos desarrolladores ya lo conocen. o Consume poca memoria y tiempo de proceso, pues no construye una representacin en arbol del documento. o Muestra el documento segn se va procesando. Desventajas: o Slo sirve para visualizar documentos en un navegador. o No permite realizar manipulaciones sobre el documento, tales como aadir y borrar elementos, realizar ordenaciones, etc. o Slo permite acceder al contenido de los elementos. No a los atributos, instrucciones de proceso, etc. o Utiliza una sintaxis diferente a la del XML.

Un ejemplo
Ejemplo de documento XML:
<?xml version="1.0" ?> <?xml-stylesheet type="text/css" href="proyectos.css" ?> <BD_Proyectos> <Proyecto pid="0511-001" tipo="Web" comienzo="11/1/05"> <Nombre_Proy> Xray Mind Learners Web Site </Nombre_Proy> <Contacto tipo="primario"> <Nombre>Kell Attain</Nombre> <Direccion> Web Ravin Consulting, 661 Oakey Rd</Direccion> <Tlf> 111-555-1111 </Tlf> <Fax> 111-555-2222 </Fax> <E-Mail> kattain@webravin.com </E-Mail> </Contacto> <Contacto tipo="marketing"> <Nombre> Francis Chillington </Nombre>

<Direccion> Web Ravin Consulting, 661 Oakey Rd</Direccion> <Tlf> 111-555-1112 </Tlf> <Fax> 111-555-2222 </Fax> <E-Mail> fchillington@webravin.com </E-Mail> </Contacto> <Contacto tipo="graficos"> <Nombre> Lara Firewalker </Nombre> <Direccion> Web Ravin Consulting, 661 Oakey Rd</Direccion> <Tlf> 111-555-1113 </Tlf> <Fax> 111-555-2222 </Fax> <E-Mail> lfirewalker@webravin.com </E-Mail> </Contacto> <Notas> <Entrada fecha="11/03/05" contacto="kta001"> Development on the Web site has started. The primary graphics - logo | backgrounds | navigation system - should be done by 11/8/00. </Entrada> </Notas> </Proyecto> <Proyecto pid="0511-002" tipo="Database"> <Nombre_Proy> XML Database for Site Visitors </Nombre_Proy> <Contacto tipo="primario"> <Nombre> Tom Phannon </Nombre> <Direccion> Web Ravin Consulting, 661 Oakey Rd</Direccion> <Tlf> 111-555-1122 </Tlf> <Fax> 111-555-2222 </Fax> <E-Mail> tphannon@webravin.com </E-Mail> </Contacto> <Notas> <Entrada fecha="11/10/05"> Database structure is complete. Ready to start propagating the data. </Entrada> </Notas> </Proyecto> <Proyecto tipo="AI"> <Nombre_Proy> House of Glass </Nombre_Proy> <Contacto tipo="primario"> <Nombre> Shamu Wagonride </Nombre> <Direccion> Web Ravin Consulting, 661 Oakey Rd</Direccion> <Tlf> 111-555-1133 </Tlf> <Fax> 111-555-2222 </Fax> <E-Mail> shamu@wagonride.com </E-Mail> </Contacto> <Notas> <Entrada fecha="11/01/05"> AI logic model software has been picked out and ordered, as well as the equipment required to run it. Networking (MIS) has been notified of the machine's arrival and networking needs. </Entrada> <Entrada fecha="11/11/05"> MIS has received equipment and software and is starting the installation. Expected date for network connection is 11/15/05. </Entrada> </Notas> </Proyecto> </BD_Proyectos>

Hoja de estilo para visualizar el documento en un navegador:


Proyecto {display: block; background: blue; font-family: sans-serif; margin: 1cm}

Nombre_Proy {display: block; background: #FF0000; font-size: larger; font-weight: bold; color: yellow; font-family: Arial; border: #FF0000;

border-style: double} Contacto {display: block; padding: 5pt; text-indent: 1cm} {display: block; font-variant: small-caps; font-size: medium; font-weight: bold; color: red}

Nombre

Direccion {display: block; font-style: italic; font-size: smaller; color: white} Tlf {display: block; font-weight: bold; font-size: smaller; color: white} {display: block; font-weight: bold; font-size: smaller; color: white} {display: block; font-weight: bold; font-style: italic; color: white} {display: block; font-style: italic; color: white; padding: 3em} {display: block}

Fax

E-Mail

Notas

Entrada

Lenguaje XSLT
Introduccin a XSLT

Para aclarar terminologa, XSL es un estndar que se compone de dos partes diferenciadas: o XSLT: Lenguaje para transformar documentos XML en otro formato (otro XML, HTML, DHTML, texto plano, PDF, RTF, Word, etc.) o XSL-FO: Especificacin que trata cmo deben ser los objetos de formato para convertir XML a formatos binarios (PDF, Word, imgenes, etc.) La principal caracterstica del lenguaje XSLT es su potencia. No es slo un lenguaje para visualizar documentos, sino en general para transformarlos y manipularlos. Esta manipulacin la gestiona un programa especial que se llama procesador XSLT. Existen distintos procesadores disponibles, como Xalan, del proyecto colaborativo de cdigo abierto Apache.

Ventajas y desventajas

Ventajas: o La salida no tiene por qu ser HTML para visualizacin en un navegador, sino que puede estar en muchos formatos. o Permite manipular de muy diversas maneras un documento XML: reordenar elementos, filtrar, aadir, borrar, etc. o Permite acceder a todo el documento XML, no slo al contenido de los elementos. o XSLT es un lenguaje XML, por lo que no hay que aprender nada especial acerca de su sintaxis. Desventajas: o Su utilizacin es ms compleja.

Consume cierta memoria y capacidad de proceso, pues se construye un rbol con el contenido del documento.

Formas de uso

Visualizar directamente en un navegador el documento XML que tiene asociada una hoja XSLT. El navegador debe tener incorporado un procesador XSLT. Ejecutar el procesador XSLT independientemente del navegador. Se le pasan las entradas necesarias (fichero origen y hoja XSLT a utilizar) y genera la salida en un fichero, con el que podemos hacer lo que queramos. Realizar las transformaciones dentro de un programa en el servidor y enviar a los clientes slo el resultado de la transformacin.

Un ejemplo de hoja
Hoja de estilo XSLT para el ejemplo del libro:
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:Lib="http://www.mislibros.com/libros/javaxml" xmlns:Catalogo="http://www.mislibros.com/catalogo" version="1.0"> <xsl:template match="Lib:Libro"> <html> <head> <title><xsl:value-of select="Lib:Titulo" /> (<xsl:value-of select="Catalogo:Seccion" />: <xsl:value-of select="Catalogo:SubSeccion" />) </title> </head> <body> <xsl:apply-templates select="Lib:Contenido" /> <i><xsl:value-of select="Lib:Copyright" /></i> </body> </html> </xsl:template> <xsl:template match="Lib:Contenido"> <center> <h1>Contenidos</h1> </center> <hr/> <ul> <xsl:for-each select="Lib:Capitulo"> <xsl:choose> <xsl:when test="@materia='Java'"> <li><xsl:value-of select="Lib:Tema" /> (Java)</li> </xsl:when> <xsl:otherwise> <li><xsl:value-of select="Lib:Tema" /> (No Java)</li> </xsl:otherwise> </xsl:choose> </xsl:for-each> </ul> </xsl:template> </xsl:stylesheet>

Caractersticas

Se puede observar que una hoja de estilo XSLT es un documento XML. El elemento raz es stylesheet, en el que se especifican los espacios de nombre para la propia hoja de estilo y para el documento XML que se quiere presentar.


XPath

Cada elemento template se asocia con un fragmento del documento XML (que puede ser un elemento o un conjunto de elementos) y se transforma en otro fragmento de XML, segn una serie de reglas que se especifican en su interior. El elemento value-of extrae un valor concreto del documento. El elemento apply-templates aplica las plantillas que se especifiquen e inserta la salida de las mismas. Para iterar sobre una serie de elementos que se repiten se utiliza for-each. Para realizar distintos procesamientos en funcin de los datos se puede utilizar el elemento choose, que se compone de un nmero de elementos when, cada uno con un caso distinto, y un elemento opcional otherwise que se refiere al caso por defecto. Para procesar o no un elemento en funcin de una condicin se utilizara simplemente el elemento if, especificando la condicin en el atributo test. El HTML que se especifica en las plantillas debe seguir las reglas del XML (es decir, debe ser XHTML).

Las expresiones que pueden aparecer en los atributos select, match o test de los elementos explicados siguen el lenguaje XPath, y pueden llegar a ser todo lo complejas que se requiera. Veamos un ejemplo sobre el mismo documento del libro con algunas expresiones XPath. Este ejemplo muestra una lista con las secciones de 3 ms apartados de captulos cuya materia sea Java, numerndolas e indicando a qu captulo pertenecen.

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:Lib="http://www.mislibros.com/libros/javaxml" version="1.0"> <xsl:template match="Lib:Libro"> <html><body> <ul> <xsl:for-each select="Lib:Contenido/Lib:Capitulo[@materia='Java'] /Lib:Seccion[@apartados>=3]"> <li> <xsl:value-of select="position()" />: <xsl:value-of select="." />, de <xsl:value-of select="preceding-sibling::Lib:Tema" /> </li> </xsl:for-each> </ul> </body></html> </xsl:template> </xsl:stylesheet>

La especificacin XPath contiene muchas complejidades que no podemos detenernos a cubrir, pero destaquemos algunos aspectos del ejemplo: o Para descender por la jerarqua de elementos se utiliza el separador /. o Se pueden imponer restricciones al conjunto de nodos extrados, entre corchetes. o Existen una serie de funciones predefinidas, como position(), que nos da el nmero de orden de un nodo respecto al conjunto de nodos extrados. o Se puede trabajar con los nodos relacionados con el actual (nodo padre, hijos, nodos al mismo nivel, etc.) mediante una serie de ejes, como preceding-sibling, que nos da los nodos anteriores al actual del mismo nivel.

Crear elementos

Con XSLT tambin es posible crear nuevos elementos mediante las etiquetas element y attribute. Esto sirve para crear elementos con algn atributo no conocido a priori, que debe tomarse del fichero XML. Aadimos el siguiente fragmento de XML al final del documento del libro, a partir del cual queremos generar enlaces HTML:

<Referencias> <Referencia> <Nombre>XSL en el W3C</Nombre> <Url>http://www.w3.org/Style/XSL</Url> </Referencia> <Referencia> <Nombre>Lista XSL</Nombre> <Url>http://www.mulberrytech.com/xsl/xsl-list</Url> </Referencia> </Referencias>

El fragmento de XSLT que genera los enlaces es:


<xsl:template match="Lib:Referencias"> <p> <center><h3>Referencias tiles</h3></center> <ol> <xsl:for-each select="Lib:Referencia"> <li> <xsl:element name="a"> <xsl:attribute name="href"> <xsl:value-of select="Lib:Url" /> </xsl:attribute> <xsl:value-of select="Lib:Nombre" /> </xsl:element> </li> </xsl:for-each> </ol> </p> </xsl:template> (Recordar aplicar la nueva plantilla:) <xsl:apply-templates select="Lib:Contenido|Lib:Referencias" />

Ordenaciones

Si queremos ordenar los captulos alfabticamente, slo tenemos que aadir lo siguiente tras el elemento for-each:
<xsl:sort select="Lib:Tema"/>

Se puede ordenar descendentemente aadiendo al elemento sort el atributo


order="descending"

Apuntes de XML
Autor: Diego Arranz Hernando

Manipulacin de XML desde programas Java o Analizar XML con SAX Introduccin a SAX El analizador SAX Un primer ejemplo El manejador de contenido Los mtodos del manejador Cdigo portable Validacin Otro ejemplo o Manipular XML con DOM Introduccin a DOM El analizador DOM Un primer ejemplo Manipulacin del rbol Cdigo portable Otro ejemplo Ms formas de manipular el rbol Crear documentos Imprimir documentos Un ejemplo Modificar documentos

Manipulacin de XML desde programas Java


Analizar XML con SAX
Introduccin a SAX

Hasta ahora hemos trabajado slo con el lenguaje XML y algunos de sus lenguajes relacionados (DTD, Esquema XML XSLT). Siendo estrictos, todava no hemos programado con XML, es decir, no hemos realizado programas que trabajen con XML. La API SAX ( API simple para XML) es el primer punto de unin del mundo de XML con el mundo de la programacin en general, y en particular con Java. Esta API consta de una serie de clases, con sus correspondientes mtodos, que nos permiten trabajar con un documento XML desde un programa escrito en Java, pudiendo acceder a los datos, comprobar si est bien formado, si es vlido, etc. La principal caracterstica de SAX es que el documento se lee secuencialmente de principio a fin, sin cargar todo el documento en memoria, lo cual tiene consecuencias positivas y negativas: o La ventaja es la eficiencia en cuanto al tiempo y la memoria empleados en el anlisis. o La desventaja es que con SAX no disponemos de la estructura en rbol de los documentos, luego no podemos modificar ni crear documentos XML, ni recorrerlos jerrquicamente, solamente analizarlos secuencialmente.

El analizador SAX

Para poder trabajar con documentos XML mediante SAX necesitamos un analizador SAX. El analizador realiza el trabajo sucio (detectar cundo empieza y termina un elemento, gestionar los espacios de nombres, comprobar que el documento est bien formado, etc.), de forma que podemos concentrarnos en los aspectos especficos de nuestra aplicacin.

Existen muchos analizadores en el mercado, pero no todos se pueden utilizar desde Java. Para los ejemplos de este curso utilizaremos el analizador Xerces, del proyecto colaborativo de cdigo abierto Apache. Para utilizar SAX desde un programa escrito en Java necesitamos conseguir las clases que componen el analizador y asegurarnos de incluir estas clases en la ruta de clases.

Un primer ejemplo

Veamos un primer ejemplo muy sencillo que simplemente analiza un documento XML e imprime un mensaje si el documento est bien formado:
java.io.IOException; org.xml.sax.SAXException; org.xml.sax.XMLReader; org.apache.xerces.parsers.SAXParser;

import import import import

public class SAX { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Analizando: " + fich + "\n"); try { XMLReader parser = new SAXParser(); parser.parse(fich); System.out.println("Fin del anlisis. Todo bien\n"); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } } }

Creamos una instancia del analizador (clase SAXParser), que vamos a manejar a travs de la interfaz XMLReader. Para analizar el documento llamamos al mtodo parse, pasndole el fichero que sea. Si hay algn problema con el anlisis se genera una excepcin SAXException y el anlisis se detiene.

El manejador de contenido

Para que nuestro programa pueda hacer algo til con los datos XML segn se analizan, debemos usar un manejador de contenido. Un manejador es una clase con una serie de mtodos. Estos mtodos se ejecutan cuando el analizador detecta determinados eventos que se producen al leer un documento (empieza el documento, se abre un elemento, se cierra, se encuentra una instruccin de proceso, etc.). Aadamos al ejemplo un esqueleto de manejador. Los mtodos se rellenarn con el cdigo apropiado para el programa que estemos realizando en cada momento:

class ManejadorPrueba implements ContentHandler { private Locator loc; public void setDocumentLocator(Locator loc) { } public void startDocument() } public void endDocument() { {

} public void processingInstruction(String destino, String datos) { } public void startPrefixMapping(String prefijo, String uri) { } public void endPrefixMapping(String prefijo) { } public void startElement(String espacio, String nomLocal, String nomCompleto, Attributes atrs) { } public void endElement(String espacio, String nomLocal, String nomCompleto) { } public void characters(char[] ch, int comienzo, int fin) { } public void ignorableWhitespace(char[] ch, int comienzo, int fin) { } public void skippedEntity(String nombre) { }

Es necesario aadir algunas lneas al cdigo anterior para utilizar el manejador:


import import import import import import import java.io.IOException; org.xml.sax.SAXException; org.xml.sax.XMLReader; org.xml.sax.Attributes; org.xml.sax.ContentHandler; org.xml.sax.Locator; org.apache.xerces.parsers.SAXParser;

public class SAX { ... XMLReader parser = new SAXParser(); ManejadorPrueba man = new ManejadorPrueba(); parser.setContentHandler(man); parser.parse(fich); System.out.println("Fin del anlisis. Todo bien\n");

... }

Los mtodos del manejador

Ahora aadiremos algo de cdigo a los mtodos del manejador para ilustrar su funcionamiento. Simplemente escribiremos mensajes por la consola cuando se detecten los eventos. Es importante notar que estamos analizando sin validar. Ms adelante realizaremos anlisis con validacin. En primer lugar rellenaremos el mtodo setDocumentLocator (que se ejecuta al principio del anlisis) guardando en una variable de nuestra clase el localizador que nos llega como parmetro. As podremos saber en qu lugar (lnea y columna) del fichero ocurren los eventos.

public void setDocumentLocator(Locator l) { loc = l; System.out.println ("Localizador guardado"); }

El comienzo y el final de un documento implican llamadas a los mtodos startDocument y endDocument:

public void startDocument() { System.out.println ("Ahora empieza el anlisis..."); } public void endDocument() { System.out.println ("...Ahora termina el anlisis"); }

El comienzo y el final de cada elemento invocan a los mtodos startElement y endElement, dentro de los cuales tenemos informacin sobre el nombre del elemento, sus atributos y el espacio de nombres al que pertenece:

public void startElement(String espacio, String nomLocal, String nomCompleto, Attributes atrs) { System.out.print("(Lnea " + loc.getLineNumber() + ") "); System.out.print("Se abre elemento: " + nomLocal); if (!espacio.equals("")) { System.out.println(" en espacio " + espacio + " (" + nomCompleto + ")"); } else { System.out.println(" sin espacio asociado"); } for (int i=0; i<atrs.getLength(); i++) { System.out.println(" Atributo: " + atrs.getLocalName(i) + "=" + atrs.getValue(i)); } } public void endElement(String espacio, String nomLocal, String nomCompleto) { System.out.println("Se cierra elemento: " + nomLocal + "\n"); }

La lectura del texto contenido en cada elemento genera una llamada al mtodo characters, dentro del cual disponemos del texto en un vector de caracteres acotado con una posicin de comienzo y otra de fin:

public void characters(char[] ch, int comienzo, int fin) { String s = new String(ch, comienzo, fin); System.out.println("Contenido: " + s); }

Algunas puntualizaciones sobre este mtodo: o No se puede contar con tener siempre todo el texto de un elemento en una nica llamada a este mtodo (grandes porciones de texto, texto y elementos hijos se entremezclan, caracteres especiales, distintos analizadores, etc.) o Puede recoger los espacios en blanco al analizar sin validacin (justo lo que estamos haciendo). Las instrucciones de proceso se controlan mediante el mtodo processingInstruction:

public void processingInstruction(String destino, String datos) { System.out.println("PI: Destino:" + destino + ", Datos:" + datos); }

Los dos mtodos que sirven para controlar las declaraciones de espacios de nombres son startPrefixMapping y endPrefixMapping. El primero se ejecuta al declarar un espacio de nombres mediante el atributo xmlns, mientras que el segundo se ejecuta al cerrar el elemento en el que se declar el espacio (normalmente el elemento raz):

public void startPrefixMapping(String prefijo, String uri) { System.out.println("Comienza el uso del prefijo " + (prefijo.equals("")? "(vaco)": prefijo) +

" correspondiente a la URI " + uri);

public void endPrefixMapping(String prefijo) { System.out.println("Termina el uso del prefijo " + (prefijo.equals("")? "(vaco)": prefijo)); }

El mtodo ignorableWhitespace lleva control de los espacios en blanco, aunque con Xerces y la mayora de analizadores no funciona bien si no estamos validando el documento:

public void ignorableWhitespace(char[] ch, int comienzo, int fin) { }

Por ltimo, el mtodo skippedEntity tiene lugar en algunos analizadores que se saltan las entidades cuando no estn validando, pero es difcil encontrar casos as:

public void skippedEntity(String nombre) { }

Cdigo portable

Hay una forma mejor de instanciar el analizador, utilizando la API JAXP, con la que podemos conseguir fcilmente que nuestros programas que usan SAX funcionen con cualquier analizador sin tener que realizar cambios en el cdigo, consiguiendo as una completa portabilidad:
java.io.IOException; org.xml.sax.SAXException; org.xml.sax.Attributes; org.xml.sax.Locator;

import import import import

import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.helpers.DefaultHandler; public class SAXconJAXP { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Analizando: " + fich + "\n"); try { SAXParser parser; SAXParserFactory factoria = SAXParserFactory.newInstance(); factoria.setNamespaceAware(true); parser = factoria.newSAXParser(); ManejadorPrueba man = new ManejadorPrueba(); parser.parse(fich, man); System.out.println("Fin del anlisis. Todo bien\n"); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } catch (ParserConfigurationException e) { System.out.println(e); } } } } class ManejadorPrueba extends DefaultHandler {

private Locator loc; public void setDocumentLocator(Locator l) { loc = l; System.out.println ("Localizador guardado"); } public void startDocument() { System.out.println ("Ahora empieza el anlisis..."); } public void endDocument() { System.out.println ("...Ahora termina el anlisis"); } public void processingInstruction(String destino, String datos) { System.out.println("PI: Destino:" + destino + ", Datos:" + datos); } public void startPrefixMapping(String prefijo, String uri) { System.out.println("Comienza el uso del prefijo " + (prefijo.equals("")? "(vaco)": prefijo) + " correspondiente a la URI " + uri); } public void endPrefixMapping(String prefijo) { System.out.println("Termina el uso del prefijo " + (prefijo.equals("")? "(vaco)": prefijo)); } public void startElement(String espacio, String nomLocal, String nomCompleto, Attributes atrs) { System.out.print("(Lnea " + loc.getLineNumber() + ") "); System.out.print("Se abre elemento: " + nomLocal); if (!espacio.equals("")) { System.out.println(" en espacio " + espacio + " (" + nomCompleto + ")"); } else { System.out.println(" sin espacio asociado"); } for (int i=0; i<atrs.getLength(); i++) { System.out.println(" Atributo: " + atrs.getLocalName(i) + "=" + atrs.getValue(i)); } } public void endElement(String espacio, String nomLocal, String nomCompleto) { System.out.println("Se cierra elemento: " + nomLocal); } public void characters(char[] ch, int comienzo, int fin) { String s = new String(ch, comienzo, fin); System.out.println("Contenido: " + s); } }

Observar que no se hace ninguna referencia al analizador a utilizar. La independencia se consigue a travs de las clases SAXParser y SAXParserFactory, debindose capturar una ParserConfigurationException. El mtodo setNamespaceAware activa el soporte para espacios de nombres. Con esta solucin, el manejador tiene que ser derivado a partir de la clase DefaultHandler, que es una clase de conveniencia en la que se sobreescriben slo los mtodos deseados (sin tener que implementar todos como ocurra con ContentHandler). Observar que la forma de pasar el manejador al analizador cambia.

Validacin

Falta completar el cdigo para que nuestro programa sea capaz de validar un documento XML a la vez que lo analiza:

... import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.SAXParseException; ... try { SAXParser parser; SAXParserFactory factoria = SAXParserFactory.newInstance(); factoria.setNamespaceAware(true); factoria.setValidating(true); parser = factoria.newSAXParser(); ManejadorPrueba man = new ManejadorPrueba(); parser.parse(fich, man); ... class ManejadorPrueba extends DefaultHandler { ... public void error(SAXParseException exc) throws SAXException { System.out.println("**Error**\n" + " Lnea: " + exc.getLineNumber() + "\n" + " URI: " + exc.getSystemId() + "\n" + " Mensaje: " + exc.getMessage()); throw new SAXException("Se encontr error"); } public void fatalError(SAXParseException exc) throws SAXException { System.out.println("**Error Fatal**\n" + " Lnea: " + exc.getLineNumber() + "\n" + " URI: " + exc.getSystemId() + "\n" + " Mensaje: " + exc.getMessage()); throw new SAXException("Se encontr error fatal");

} }

Para informar de los errores que se detecten al validar necesitamos aadir nuevos mtodos al manejador. Los errores referentes a la validacin provocan una llamada al mtodo error, mientras que los errores que afectan a la sintaxis XML invocan al mtodo fatalError. Los errores de validacin no tienen por qu detener el anlisis, slo lo hacen si lanzamos una excepcin desde el mtodo error. Los errores de sintaxis siempre detienen el anlisis, lancemos o no una excepcin. La validacin se puede realizar mediante una DTD o un esquema XML, segn lo que indique el documento XML (no hace falta cambiar nada en el cdigo Java).

Otro ejemplo

Para terminar, veamos el cdigo de un manejador para el ejemplo del libro que imprime por pantalla el ttulo del libro, las lneas del fichero en que empieza cada captulo, el nmero de captulos y las materias de las que trata el libro:

class ManejadorLibro extends DefaultHandler { private Locator l; private boolean titulo; private int numCaps; private HashSet materias; public void setDocumentLocator(Locator l) { this.l = l; } public void startDocument() { numCaps = 0; materias = new HashSet(); } public void startElement(String espacio, String nomLocal, String nomCompleto, Attributes atrs) { if (nomLocal.equals("Titulo")) { titulo = true; } else if (nomLocal.equals("Capitulo")) { numCaps++; System.out.println("Captulo en lnea: " +l.getLineNumber()); materias.add(atrs.getValue(0)); } } public void endElement(String espacio, String nomLocal, String nomCompleto) { if (nomLocal.equals("Titulo")) { titulo = false; } } public void characters(char[] ch, int comienzo, int fin) { if (titulo) { String cad = new String(ch, comienzo, fin); System.out.println("El ttulo es: " + cad); } } public void endDocument() { System.out.println("Nmero de captulos: " + numCaps); System.out.print("Materias: "); Iterator i = materias.iterator(); while (i.hasNext()) { System.out.print(i.next() + " "); } System.out.println(); } }

Manipular XML con DOM


Introduccin a DOM

La API DOM ( Modelo de Objetos de Documento) constituye un paso ms all en el uso de XML desde un lenguaje de programacin, y en particular desde Java. Esta API tambin consta de una serie de clases y mtodos, que nos permiten trabajar con los documentos XML desde nuestros programas escritos en Java. La principal caracterstica de DOM es que el documento con el que se trabaja se carga entero en memoria, en una estructura de rbol, por lo que la forma de trabajar con DOM es muy distinta a la de SAX: o La ventaja es que con DOM, al disponer de la estructura del documento, podemos acceder a los datos en funcin de la jerarqua de elementos, as como modificar el contenido de los documentos e incluso crearlos desde cero.

La desventaja es el coste en tiempo y memoria que conlleva construir el rbol para un documento, sobre todo si tiene cierto tamao.

El analizador DOM

Para poder trabajar con DOM necesitamos un analizador DOM. El analizador DOM lee un documento XML y genera una estructura en rbol para l, para lo cual se suele apoyar en un analizador SAX. Para los ejemplos de DOM utilizaremos tambin el analizador Xerces (dado que ya tenemos sus clases y hemos establecido tambin la ruta de clases slo tendremos que importar las clases oportunas para trabajar con DOM)

Un primer ejemplo

Veamos un primer ejemplo sencillo que lee un documento XML y genera un rbol para l:
org.w3c.dom.Document; java.io.IOException; org.xml.sax.SAXException; org.apache.xerces.parsers.DOMParser;

import import import import

public class DOM { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Generando rbol para: " + fich + "\n"); try { DOMParser parser = new DOMParser(); parser.parse(fich); Document doc = parser.getDocument(); System.out.println("Fin de la carga. Todo bien\n"); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } } } }

Necesitamos una instancia del analizador (clase DOMParser). Veremos ms adelante cmo se consigue independencia del analizador por medio de la API JAXP. Para generar el rbol llamamos al mtodo parse, pasndole el fichero que sea. Despus, con el mtodo getDocument obtenemos un objeto que referencia al rbol creado, y que podemos manipular de mltiples formas. Si hay algn problema con la sintaxis del documento XML se genera una excepcin SAXException y el proceso se detiene.

Manipulacin del rbol

Para ilustrar el manejo de DOM vamos a imprimir el documento XML que se nos pase como entrada. Para ello necesitamos realizar un procesamiento recursivo: procesamos cada nodo del rbol y despus procesamos sus nodos hijos recursivamente. Aadimos un mtodo tratarNodo que va a ser llamado recursivamente:

import org.w3c.dom.Document; import org.w3c.dom.Node;

import java.io.IOException; ... public class DOM { public static void tratarNodo(Node nodo) { switch (nodo.getNodeType()) { case Node.DOCUMENT_NODE: break; case Node.ELEMENT_NODE: break; case Node.ATTRIBUTE_NODE: break; case Node.TEXT_NODE: break; case Node.CDATA_SECTION_NODE: break; case Node.PROCESSING_INSTRUCTION_NODE: break; case Node.ENTITY_REFERENCE_NODE: break; case Node.DOCUMENT_TYPE_NODE: break; } }

public static void main(String[] args) { ... Document doc = parser.getDocument(); tratarNodo(doc); System.out.println("Fin de la carga. Todo bien\n"); ... } }

Dentro de este mtodo se realizarn tres tareas: o Determinar el tipo del nodo en curso. o Imprimir por pantalla el contenido del nodo. o Tratar recursivamente los nodos hijos del nodo en curso. La primera tarea se realiza con el mtodo getNodeType, como puede verse en el esquema de cdigo. Ahora completaremos cada caso para realizar las otras dos. El primer nodo que nos encontramos representa todo el documento (tipo DOCUMENT_NODE). Aqu imprimiremos la declaracin XML. Despus con getDocumentElement accedemos al nodo que representa al elemento raz, y lo pasamos recursivamente al mtodo tratarNodo:

case Node.DOCUMENT_NODE: System.out.println("<xml version=\"1.0\">"); Document doc = (Document)nodo; tratarNodo(doc.getDocumentElement()); break;

Los elementos del documento estn representados por un nodo ELEMENT_NODE. Obtenemos el nombre de cada elemento con getNodeName. Con getChildNodes obtenemos los hijos en una NodeList, que hay que recorrer para tratar recursivamente cada hijo.
org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.NodeList; java.io.IOException;

import import import import

... case Node.ELEMENT_NODE: String nombre = nodo.getNodeName(); System.out.print("<" + nombre); System.out.println(">"); NodeList hijos = nodo.getChildNodes(); if (hijos != null) { for (int i=0; i<hijos.getLength(); i++) { tratarNodo(hijos.item(i)); } } System.out.println("</" + nombre + ">"); break;

Para obtener los atributos de un elemento tenemos el mtodo getAttributes, que devuelve un NamedNodeMap, el cual procesamos para tratar los atributos recursivamente. Cada atributo es un nodo ATTRIBUTE_NODE, cuyo nombre y valor recuperamos con getNodeName y getNodeValue:
import import import import import ... org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.NodeList; org.w3c.dom.NamedNodeMap; java.io.IOException;

case Node.ELEMENT_NODE: String nombre = nodo.getNodeName(); System.out.print("<" + nombre); NamedNodeMap ats = nodo.getAttributes(); for (int i=0; i<ats.getLength(); i++) { tratarNodo(ats.item(i)); } System.out.println(">"); NodeList hijos = nodo.getChildNodes(); ... break; case Node.ATTRIBUTE_NODE: System.out.print(" " + nodo.getNodeName() + "=\"" + nodo.getNodeValue() + "\"");

Para que la salida sea ms fcil de leer colocamos un sangrado que vamos aumentando recursivamente:

public static void tratarNodo(Node nodo, String ind) { switch (nodo.getNodeType()) { case Node.DOCUMENT_NODE: System.out.println("<xml version=\"1.0\">"); Document doc = (Document)nodo; tratarNodo(doc.getDocumentElement(), ""); break; case Node.ELEMENT_NODE: String nombre = nodo.getNodeName(); System.out.print(ind + "<" + nombre); NamedNodeMap ats = nodo.getAttributes(); for (int i=0; i<ats.getLength(); i++) { tratarNodo(ats.item(i), ""); } System.out.println(">"); NodeList hijos = nodo.getChildNodes(); if (hijos != null) { for (int i=0; i<hijos.getLength(); i++) { tratarNodo(hijos.item(i), ind + " "); }

} System.out.println(ind + "</" + nombre + ">"); break; ... public static void main(String[] args) { ... Document doc = parser.getDocument(); tratarNodo(doc, ""); System.out.println("Fin de la carga. Todo bien\n"); ...

El texto de los elementos viene recogido en nodos TEXT_NODE o CDATA_SECTION_NODE, en los cuales slo tenemos que hacer una llamada a getNodeValue para obtener el texto:

case Node.TEXT_NODE: String texto = nodo.getNodeValue().trim(); if (!texto.equals("")) { System.out.println(ind + texto); } break; case Node.CDATA_SECTION_NODE: System.out.println(nodo.getNodeValue()); break;

Slo nos faltan unos ltimos detalles: el cdigo para procesar las instrucciones de proceso, la declaracin DTD y las referencias a entidades:
org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.NodeList; org.w3c.dom.NamedNodeMap; org.w3c.dom.DocumentType; java.io.IOException;

import import import import import import ...

case Node.PROCESSING_INSTRUCTION_NODE: System.out.println("<?" + nodo.getNodeName() + " " + nodo.getNodeValue() + "?>"); break; case Node.DOCUMENT_TYPE_NODE: DocumentType dt = (DocumentType)nodo; System.out.println("<!DOCTYPE " + dt.getName() + " SYSTEM \"" + dt.getSystemId() + "\">"); break; case Node.ENTITY_REFERENCE_NODE: System.out.println(ind + "&" + nodo.getNodeName() + ";"); break;

Y modificar el tratamiento del nodo del documento para que trate todos sus nodos hijos, ya que las instrucciones de proceso y la declaracin DTD lo son:

case Node.DOCUMENT_NODE: System.out.println("<xml version=\"1.0\">"); Document doc = (Document)nodo; tratarNodo(doc.getDocumentElement(), ""); NodeList nodos = nodo.getChildNodes(); if (nodos != null) { for (int i=0; i<nodos.getLength(); i++) { tratarNodo(nodos.item(i), ""); } } break;

Cdigo portable

...

Podemos utilizar la API JAXP para conseguir independencia del analizador, de una forma anloga a como lo hicimos con SAX:

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; public class DOMconJAXP { ... public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Generando rbol para: " + fich + "\n"); try { DocumentBuilder parser; DocumentBuilderFactory factoria = DocumentBuilderFactory.newInstance(); parser = factoria.newDocumentBuilder(); Document doc = parser.parse(fich); tratarNodo(doc, ""); System.out.println("Fin de la carga. Todo bien\n"); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } catch (ParserConfigurationException e) { System.out.println(e); } } } }

Otro ejemplo

Ejemplo DOM para el documento del libro. Imprime por pantalla el ttulo del libro, el nmero de captulos y las materias de las que trata el libro:
org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.NodeList; org.w3c.dom.NamedNodeMap; java.io.IOException; org.xml.sax.SAXException;

import import import import import import

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.util.HashSet; import java.util.Iterator; public class EjemploDOM { static int numCaps = 0; static HashSet materias = new HashSet();

public static void procesar(Node nodo) { String nombre = nodo.getNodeName(); if (nombre.equals("Libro")) { NodeList hijos = nodo.getChildNodes(); for (int i=0; i<hijos.getLength(); i++) { procesar(hijos.item(i)); } System.out.println("Num Captulos: " + numCaps); System.out.print("Materias: "); Iterator i = materias.iterator(); while (i.hasNext()) { System.out.print(i.next() + " "); } System.out.println(); } else if (nombre.equals("Contenido")) { NodeList hijos = nodo.getChildNodes(); for (int i=0; i<hijos.getLength(); i++) { procesar(hijos.item(i)); } } else if (nombre.equals("Titulo")) { NodeList hijos = nodo.getChildNodes(); System.out.println("Ttulo: " + hijos.item(0).getNodeValue()); } else if (nombre.equals("Capitulo")) { numCaps++; NamedNodeMap ats = nodo.getAttributes(); materias.add(ats.item(0).getNodeValue()); } }

public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Generando rbol para: " + fich + "\n"); try { DocumentBuilder parser; DocumentBuilderFactory factoria = DocumentBuilderFactory.newInstance(); parser = factoria.newDocumentBuilder(); Document doc = parser.parse(fich); procesar(doc.getDocumentElement()); System.out.println("Fin. Todo bien\n"); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } catch (ParserConfigurationException e) { System.out.println(e); }

} } }

Ms formas de manipular el rbol

Casi todos los mtodos que hemos visto para trabajar con DOM estn definidos en la interfaz Node. Existen un par de mtodos muy tiles definidos en la interfaz Element, que hereda de Node:

Para recuperar una serie de elementos por su nombre, no necesariamente hijos directos, tenemos getElementsByTagName, que devuelve una NodeList. Este mtodo tambin est definido en la interfaz Document. o Para recuperar el valor de un atributo a partir de su nombre, tenemos getAttribute. Ms mtodos tiles, stos otra vez en la interfaz Node: o Para extraer el primer hijo de un nodo, getFirstChild. Es muy til para conseguir el texto de un elemento. o Para extraer el padre de un nodo, getParentNode. Ilustraremos estos mtodos con un pequeo programa ejemplo que muestra por pantalla todas las secciones de un libro, con su nmero de apartados y captulo al que pertenecen:
org.w3c.dom.Document; org.w3c.dom.NodeList; org.w3c.dom.Node; org.w3c.dom.Element; java.io.IOException; org.xml.sax.SAXException; javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; javax.xml.parsers.ParserConfigurationException;

import import import import import import import import import

public class PeqEjemploDOM { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Generando rbol para: " + fich + "\n"); try { DocumentBuilder parser; DocumentBuilderFactory factoria = DocumentBuilderFactory.newInstance(); parser = factoria.newDocumentBuilder(); Document doc = parser.parse(fich); NodeList secciones = doc.getElementsByTagName("Seccion"); for (int i=0; i<secciones.getLength(); i++) { Element sec = (Element)secciones.item(i); System.out.print(sec.getFirstChild().getNodeValue()); System.out.print(" (" + sec.getAttribute("apartados") + ", "); Element padre = (Element)sec.getParentNode(); Node tema = padre.getElementsByTagName("Tema").item(0); System.out.println(tema.getFirstChild().getNodeValue() + ")"); } } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } catch (ParserConfigurationException e) { System.out.println(e); }

} } }

Observar que realizar el mismo programa mediante SAX sera un poco engorroso.

Crear documentos

Nos queda pendiente crear un documento desde cero con DOM.

Al no estar estandarizada esta tarea, los detalles concretos dependen del analizador que se utilice. Primeramente necesitamos instanciar una
clase concreta

que implemente el interfaz Document. En el caso de Xerces es DocumentImpl.

Los mtodos ms importantes para ir componiendo el documento son: o createElement crea un nodo para un elemento (Interfaz Document). o setAttribute crea un atributo para un elemento (Interfaz Element). o createTextNode crea un nodo de tipo texto (Interfaz Document). o appendChild sirve para agregar un nodo hijo a un nodo padre, al final de su lista de nodos hijos (Interfaz Node). o Existen otros mtodos definidos en Document que crean otros tipos de nodos, como instrucciones de proceso, secciones CDATA o referencias a entidad.

Imprimir documentos

Una vez que hemos creado el documento, podemos imprimirlo en un flujo (por pantalla, a un fichero, etc.). Al no estar estandarizada esta tarea, los detalles concretos dependen del analizador que se utilice. En el caso de Xerces, necesitamos instanciar la clase XMLSerializer, especificando el flujo por el que vamos a escribir y un formato. Despus pasamos nuestro documento al mtodo serialize.

Un ejemplo

En el siguiente ejemplo crearemos un pequeo documento con los datos de una persona y lo imprimiremos por pantalla y a un fichero.
java.io.IOException; java.io.StringWriter; java.io.FileWriter; org.w3c.dom.Document; org.w3c.dom.Element; org.w3c.dom.ProcessingInstruction; org.apache.xerces.dom.DocumentImpl; org.apache.xml.serialize.OutputFormat; org.apache.xml.serialize.Serializer; org.apache.xml.serialize.SerializerFactory; org.apache.xml.serialize.XMLSerializer;

import import import import import import import import import import import

public class CrearDOM { public static void main( String[] argv ) { try { Document doc= new DocumentImpl(); Element raiz = doc.createElement("Persona"); raiz.setAttribute("DNI", "1234567"); Element elem = doc.createElement("Nombre"); elem.appendChild(doc.createTextNode("Juan Prez")); raiz.appendChild(elem); elem = doc.createElement("Edad"); elem.appendChild(doc.createTextNode("28")); raiz.appendChild(elem); elem = doc.createElement("Altura"); elem.appendChild(doc.createTextNode("1.75")); raiz.appendChild(elem); elem = doc.createElement("Direccin"); Element elemHijo = doc.createElement("Calle"); elemHijo.appendChild(doc.createTextNode("Castellana")); elem.appendChild(elemHijo); elemHijo = doc.createElement("Nmero");

elemHijo.appendChild(doc.createTextNode("155")); elem.appendChild(elemHijo); raiz.appendChild(elem); ProcessingInstruction pi = doc.createProcessingInstruction("miPI", "atr=\"prueba\""); doc.appendChild(pi); doc.appendChild(raiz); OutputFormat formato = new OutputFormat(doc, "UTF-8", true); StringWriter s = new StringWriter(); XMLSerializer ser = new XMLSerializer(s, formato); ser.serialize(doc); System.out.println(s.toString()); FileWriter f = new FileWriter("persona.xml"); ser = new XMLSerializer(f, formato); ser.serialize(doc); } catch (IOException e) { System.out.println(e); }

} }

Modificar documentos

Tambin podemos modificar un documento DOM por medio de los siguientes mtodos definidos en Node: o insertBefore agrega un nodo hijo a otro nodo, permitiendo especificar la posicin concreta en la lista de hijos (el hijo que va a quedar detrs del nuevo). o removeChild elimina un nodo hijo. o replaceChild reemplaza un nodo hijo por otro. o removeAttribute elimina un atributo de un nodo (este mtodo se define en Element).

Apuntes de XML
Autor: Diego Arranz Hernando

XML y las bases de datos o Generar XML a partir de consultas o Transferir datos desde documentos XML o Herramientas o XML como almacn de datos

XML y las bases de datos


Generar XML a partir de consultas

Para generar XML a partir de datos almacenados en una base de datos, es necesario llevar a cabo dos tareas: o Ejecutar hacia la base de datos la consulta deseada. o Construir un documento XML a partir de los datos obtenidos por la consulta. La forma ms cmoda de hacer esto es por medio de DOM. Veamos un ejemplo que ilustra esto:
java.io.*; java.sql.*; org.w3c.dom.*; org.apache.xerces.dom.DocumentImpl; org.apache.xml.serialize.*;

import import import import import

class BDToXML { public static void main(String args[]) { try{ Class.forName("com.inet.tds.TdsDriver"); String url = "jdbc:inetdae7:localhost?database=Northwind"; Connection con = DriverManager.getConnection(url,"sa",""); Statement st = con.createStatement(); String sql = "SELECT * FROM CUSTOMERS"; ResultSet res = st.executeQuery(sql); Document doc = new DocumentImpl(); Element raiz = doc.createElement("Resultado"); ResultSetMetaData rMeta = res.getMetaData(); int nCols = rMeta.getColumnCount(); while (res.next()) { Element reg = doc.createElement("Elemento"); reg.setAttribute(rMeta.getColumnName(1), res.getString(1)); for(int i=2; i<=nCols; i++) { Element campo = doc.createElement(rMeta.getColumnName(i)); campo.appendChild(doc.createTextNode(res.getString(i))); reg.appendChild(campo); } raiz.appendChild(reg); } doc.appendChild(raiz); con.close(); OutputFormat formato = new OutputFormat(doc, "UTF-8", true); StringWriter s = new StringWriter(); XMLSerializer ser = new XMLSerializer(s, formato); ser.serialize(doc); System.out.println(s.toString()); } catch(ClassNotFoundException ex){ System.out.println(ex);

} }

} catch(SQLException ex){ System.out.println(ex); } catch(IOException ex){ System.out.println(ex); }

La primera parte del cdigo ejecuta la consulta deseada y obtiene los resultados en un objeto de la clase ResultSet. Para ello es necesario previamente cargar un controlador y especificar una URL acordes con la BD que se desee utilizar. Estas instrucciones y otras que siguen corresponden a la API JDBC, cuyos detalles estn ms all del alcance de este curso. Despus se trata de transferir los datos del objeto ResultSet a un rbol DOM. En este ejemplo concreto cada registro de los resultados se convierte en un elemento XML. El primer campo se convierte en un atributo y el resto en subelementos. Una vez creado el rbol DOM, imprimimos el documento XML por pantalla, aunque fcilmente se podra llevar a un fichero o realizar alguna otra accin.

Transferir datos desde documentos XML



El paso de datos en XML a una base de datos es un poco ms engorroso. Se trata de construir y ejecutar una serie de sentencias SQL de insercin a partir de los datos contenidos en el documento XML. Veamos los detalles de esta tarea con un ejemplo:
java.io.*; java.sql.*; org.w3c.dom.*; org.xml.sax.SAXException; javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; javax.xml.parsers.ParserConfigurationException;

import import import import import import import

class XMLToBD { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Generando rbol para: " + fich + "\n"); try { Class.forName("com.inet.tds.TdsDriver"); String url = "jdbc:inetdae7:localhost?database=Northwind"; Connection con = DriverManager.getConnection(url,"sa",""); Statement st = con.createStatement(); DocumentBuilder parser; DocumentBuilderFactory factoria = DocumentBuilderFactory.newInstance(); parser = factoria.newDocumentBuilder(); Document doc = parser.parse(fich); Element raiz = doc.getDocumentElement(); String tabla = raiz.getNodeName(); String sqlFija = "INSERT INTO " + tabla + "("; String nombre = tabla.substring(0, tabla.length() - 1); NodeList elems = raiz.getElementsByTagName(nombre); Node primero = elems.item(0); NodeList campos = primero.getChildNodes(); for (int i=0; i<campos.getLength(); i++) {

Node n = campos.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { sqlFija += ((i==1)? "" : ", ") + n.getNodeName(); } } sqlFija += ") VALUES "; for (int i=0; i<elems.getLength(); i++) { String sqlVar = "("; Node n = elems.item(i); NodeList hijos = n.getChildNodes(); for (int j=0; j<hijos.getLength(); j++) { Node hijo = hijos.item(j); if (hijo.getNodeType() == Node.ELEMENT_NODE) { sqlVar += ((j==1)? "'" : ", '") + hijo.getFirstChild().getNodeValue() + "'"; } } sqlVar += ")"; st.executeUpdate(sqlFija + sqlVar); System.out.println(sqlFija); System.out.println(sqlVar); System.out.println(); } } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } catch (ParserConfigurationException e) { System.out.println(e); } catch(ClassNotFoundException ex){ System.out.println(ex); } catch(SQLException ex){ System.out.println(ex); }

} } }

En la primera parte se realiza la conexin con la BD y se deja preparado un objeto Statement que nos servir para ejecutar las sentencias de insercin. Posteriormente obtenemos el rbol DOM para el documento XML de origen. A partir del elemento raz y el primer subelemento de ste, construmos la primera parte del SQL necesario para realizar inserciones de registros. Esta parte ser fija para todas las inserciones, y contiene el nombre de la tabla y los nombres de sus campos. Despus, para cada elemento del documento XML que cuelgue del elemento raz completamos la sentencia de insercin con los valores contenidos en el elemento y ejecutamos la sentencia. En este ejemplo concreto se ha supuesto que el nombre del elemento raz coincide con la tabla destino y que los elementos que cuelgan del raz se nombran con el singular del elemento raz.

Herramientas

Hemos visto ejemplos de la programacin del proceso de conversin XML BD en ambos sentidos, por medio de las APIs DOM y JDBC. Existen APIs de ms alto nivel que nos ayudan en la programacin de ese proceso. Tambin existen multitud de productos que nos proporcionan automticamente esa conversin mediante un interfaz visual. Cada forma de realizar la conversin tiene su punto fuerte:

o o

La programacin nos proporciona un completo control sobre el proceso de transformacin y es vlida en mayor nmero de circunstancias, a costa de un mayor trabajo. Las herramientas automticas facilitan mucho el trabajo, a costa de menos control en el proceso y menor rango de situaciones de uso.

XML como almacn de datos



Hemos visto ampliamente cmo XML es un formato totalmente orientado hacia los datos. Vimos en la introduccin que uno de los usos de XML es la configuracin. Hay ejemplos reales bastante importantes de este uso, como los descriptores para EJBs, o la configuracin del servidor de servlets Apache Tomcat. Lo siguiente es preguntarnos si podramos llegar a tener como base de datos un sistema que funcione exclusivamente con XML. Dicho sistema nos ahorrara las conversiones que hemos analizado en los apartados anteriores, ganando principalmente en rapidez. Hay una serie de problemas que van en contra, al menos a corto plazo, de esta posibilidad: o Multitud de aplicaciones (por no decir casi todas) que utilizan actualmente algn sistema de bases de datos relacionales (Oracle, SQL Server, Sybase, MySQL, etc.). o Tamao de las bases de datos necesarias. o Representacin en XML de datos relaciones. De todas formas, ya existen multitud de sistemas de BBDD que funcionan exclusivamente con XML y que pueden ser vlidos en determinadas circunstancias (pequeas cantidades de datos, sistemas no heredados, etc.).

Apuntes de XML
Autor: Diego Arranz Hernando

Otros temas de inters o XLink o JDOM Otra API ms Ventajas y desventajas Una API en desarrollo o Marcos de publicacin web El problema Soluciones con tecnologa conocida Contenido y presentacin La solucin: marcos de publicacin web Ventajas Un ejemplo de marco de publicacin: Cocoon

Otros temas de inters


XLink

Es un lenguaje XML que nos permite especificar enlaces entre documentos XML. Ofrece muchas ms posibilidades de enlace que el elemento <a href=...> ... </a> recogido en el estndar HTML. Veamos un ejemplo de cdigo:

<environment xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="extended"> <artist xlink:type="locator" xlink:label="artist" xlink:href="modigliani.xml"/> <influence xlink:type="locator" xlink:label="inspiration" xlink:href="cezanne.xml"/> <influence xlink:type="locator" xlink:label="inspiration" xlink:href="lautrec.xml"/> <influence xlink:type="locator" xlink:label="inspiration" xlink:href="rouault.xml"/> <history xlink:type="locator" xlink:label="period" xlink:href="paris.xml"/> <history xlink:type="locator" xlink:label="period" xlink:href="kisling.xml"/> <bind xlink:type="arc" xlink:from="artist" xlink:to="inspiration"/> <bind xlink:type="arc" xlink:from="artist" xlink:to="period"/> </environment>

En XLink existen dos tipos de enlaces: simples (como los elementos a img de HTML) y extendidos. Los recursos y enlaces se representan con elementos, pudiendo elegir libremente el nombre de los mismos. Para recursos externos se usa el tipo locator, para recursos internos resource. Para especificar finalmente los enlaces se usa el tipo arc. Como se puede observar, la caracterstica ms atractiva de XLink es que podemos tener enlaces mltiples. Existe un lenguaje complementario, Xpointer (basado en Xpath), que permite realizar enlaces a partes de un documento o incluso a elementos individuales. Para que XLink y Xpointer sean realmente tiles se deben ir implementando progresivamente en los navegadores.

JDOM

Otra API ms

Es otra API para manipular documentos XML, pero slo desde programas escritos en Java. Pretende ser una alternativa a la API DOM, con las siguientes caractersticas principales: o Ms fcil de usar. o Ms adecuada a Java. o Ms rpida. o Independiente de cualquier analizador (recordar problemas con la creacin y serializacin de documentos). o Que se integre bien con SAX y DOM. A continuacin se muestra un ejemplo que extrae el ttulo y los captulos del documento del libro, utilizando para ello JDOM:
java.io.File; java.util.List; org.jdom.input.DOMBuilder; org.jdom.*;

import import import import

public class PeqEjemplo { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Generando rbol para: " + fich + "\n"); try { DOMBuilder b = new DOMBuilder("org.jdom.adapters.XercesDOMAdapter"); Document doc = b.build(new File(fich)); Element raiz = doc.getRootElement(); Namespace ns = Namespace.getNamespace ("http://www.mislibros.com/libros/javaxml"); Element tit = raiz.getChild("Titulo", ns); System.out.println(tit.getText() + "\n"); Element cont = raiz.getChild("Contenido", ns); List caps = cont.getChildren("Capitulo", ns); for (int i=0; i<caps.size(); i++) { Element cap = (Element)caps.get(i); System.out.println(cap.getChildText("Tema", ns)); } } catch (JDOMException e) { System.out.println(e); } } }

Ventajas y desventajas

Como aspectos positivos de JDOM, a modo de ejemplo, se pueden observar los siguientes, que facilitan el trabajo con los documentos XML: o El mtodo getText() devuelve directamente el texto contenido en un elemento, mientras que la forma ms simple de hacerlo con DOM sera getFirstChild().getNodeValue(). o Otro mtodo muy til es getChildText(), que devuelve el texto de un hijo. Esta misma tarea con DOM requerira bastante ms cdigo. o Se utilizan clases estndar del estilo List y Map, incluidas en Java desde su versin 1.2, en lugar de las clases NodeList y NamedNodeMap que vienen con DOM. o Existen una serie de adaptadores que permiten construir un documento especificando un determinado analizador, pero sin necesidad de importar explcitamente la clase necesaria (portabilidad). En cuanto a los aspectos negativos de JDOM, tambin a modo de ejemplo: o No existe un mtodo equivalente al muy til getElementsByTagName que con DOM nos permita obtener elementos de cualquier nivel por debajo del actual.

Es necesario especificar el espacio de nombres, incluso cuando se trabaja sin prefijo alguno.

Una API en desarrollo

De cualquier forma, la API JDOM todava se encuentra en fase beta, por lo que es previsible que cambie algo hasta la finalizacin de la versin 1.0. Actualmente forma parte del JCP (Java Community Process) mediante una JSR (Java Specification Request), por lo que seguramente formar parte de una versin futura del JDK.

Marcos de publicacin web


El problema

Imaginemos un gran sitio web formado por decenas o incluso cientos de pginas HTML. Se desea permitir un acceso mltiple al contenido a travs de un navegador o a travs de mviles WAP (sin descartar ms formas de acceso en el futuro), e incluso que se puedan imprimir los contenidos con calidad utilizando un formato como PDF. Tambin es deseable que se pueda realizar sin demasiada dificultad un completo cambio de imagen en todo el sitio web.

Soluciones con tecnologa conocida

Las hojas de estilo en cascada (CSS) pueden ayudar un poco en esta tarea, pero no lo suficiente. Con un sistema basado en Java Servlets se debera cambiar el cdigo de stos, e incluso aadir ms servlets, con las consiguientes recompilaciones, configuraciones y riesgos para el funcionamiento del sistema. Una solucin bastante buena es el uso de pginas JSP, sobre todo si se combina con el uso de beans y libreras de etiquetas.

Contenido y presentacin

De lo que se trata en el fondo es de hallar la mejor forma de separar contenido y presentacin. Por un lado tendramos el contenido, los datos, y por otro lado distintas vistas o formas de presentar los datos. De esta forma un cambio de imagen slo afecta a una o varias vistas. La necesidad de mostrar los datos en otro formato slo implica la creacin de otra vista.

La solucin: marcos de publicacin web

Un marco de publicacin es un sistema que sirve contenido web aplicando los principios de la separacin entre contenido y presentacin que hemos visto. Para el contenido se utiliza XML y para la presentacin XSL (tanto XSLT como XSL-FO). Ms en detalle, un marco de publicacin web XML/XSL es un sistema que: o Admite peticiones de documentos en diversos formatos. o Obtiene la informacin adecuada de las posibles fuentes de datos XML. o Obtiene la informacin sobre las transformaciones XSL necesarias y se las aplica a los datos. o Formatea el resultado final y lo sirve como respuesta a la peticin inicial.

Ventajas

Separacin limpia entre contenido y presentacin (que lleva consigo la separacin clara entre distintos roles de trabajo). Proporciona una mejora muy notable del mantenimiento: se puede realizar un cambio radical de imagen de todo un site web con tan solo modificar las hojas XSL y sin tocar ni una sola lnea de cdigo.

A partir de un solo documento XML con el contenido, se pueden obtener pginas HTML para su presentacin web, pginas WML para dispositivos WAP, documentos PDF para imprimir, etc. Aunque no hay ningn estndar que regule cmo debe ser un sistema de publicacin, si que est basado en estndares con mucha fuerza en el mercado, por lo que es ms sencillo pasar de usar uno a usar otro. Es compatible con el resto de tecnologas web como servlets, JSPs...

Un ejemplo de marco de publicacin: Cocoon

La principal desventaja de estos sistemas es la poca madurez de la mayora. El ms maduro y reconocido en este momento es Cocoon, cuya versin 2.0 ya se encuentra disponible, con muchas mejoras en cuanto a facilidad de uso y eficiencia sobre la serie 1.x. Veamos algunas de sus caractersticas: o Forma parte del proyecto colaborativo de cdigo abierto Apache. o Es altamente configurable. Por ejemplo, podemos elegir el analizador XML y el procesador XSLT que ms nos gusten. o Permite diferenciar el procesado del documento en funcin del dispositivo o tipo de software que realiza la peticin. o Incorpora un sistema de cach que permite un rendimiento muy elevado. o Puede trabajar como un programa en lnea de comandos pero su uso normal es como un sistema de servlets para la publicacin a travs de la Web. o Incorpora las pginas XSP, que son documentos XML que aparte de contenido esttico incluyen lgica para crear XML dinmicamente. Son parecidas a las pginas JSP, pero pretenden solucionar algunos problemas de stas.

Apuntes de XML
Autor: Diego Arranz Hernando

Servicios web o Introduccin o Terminologa Tecnologas estndar APIs Java o JAXR Registros Introduccin a JAXR Un cliente JAXR o JAXM Mensajes SOAP Introduccin a JAXM Ejemplos o JAX-RPC Introduccin Un ejemplo

Servicios web
Introduccin

Veamos una definicin formal de un servicio web: "Aplicacin modular, auto-contenida y autodescriptiva que puede ser publicada, localizada e invocada a travs de Internet". Los servicios web hacen posible la comunicacin entre aplicaciones en Internet, donde conviven mltiples plataformas y aplicaciones construidas en diversos lenguajes. En los ltimos aos se han venido utilizando otras tecnologas como RMI, CORBA o DCOM, pero ninguna de ellas asegura una compatibilidad total. Los servicios web hacen posible esta compatibilidad al estar basados en tecnologas estndar e independientes de plataformas y lenguajes, como HTTP, WSDL, UDDI, SOAP o XML-RPC.

Terminologa
Tecnologas estndar

WSDL: Lenguaje para describir servicios web. UDDI: Especificacin para registros de servicios web. SOAP: Lenguaje que especifica la forma de enviar mensajes XML a travs de Internet. XML-RPC: Mecanismo para invocacin remota de procedimientos (mtodos) utilizando XML como forma de comunicacin.

APIs Java

JAXR: Acceso a directorios de servicios. JAXM: Envo de mensajes XML. JAX-RPC: Uso de XML-RPC desde Java.

JAXR
Registros

Un registro es una infraestructura que facilita el descubrimiento de servicios web. Este tipo de registros se encuentran disponibles para cualquier organizacin, normalmente como un servicio web ms. Existen varias especificaciones para estos registros, las ms importantes: o UDDI, desarrollada por una serie de empresas. o ebXML, desarrollada por las organizaciones OASIS y U.N./CEFACT

Introduccin a JAXR

Es una API para Java que permite trabajar con los registros de servicios web sin preocuparnos de los detalles de los documentos XML que intervienen en las operaciones. Es independiente del tipo de registro concreto al que accedemos, pues se utiliza un modelo de contenido unificado. Permite realizar las siguientes operaciones bsicas: buscar servicios web disponibles, publicar servicios web, modificar los datos de un servicio, eliminar un servicio.

Un cliente JAXR

A continuacin mostramos el cdigo de un programa que busca servicios web en un registro a partir de una cadena de caracteres de entrada.
javax.xml.registry.*; javax.xml.registry.infomodel.*; java.net.*; java.util.*;

import import import import

public class JAXRQuery { public static void main(String[] args) { if (args.length != 1) { System.out.println("Usage: java " + "JAXRQuery <query-string>"); System.exit(1); } String queryString = new String(args[0]); System.out.println("Query string is " + queryString); JAXRQuery jq = new JAXRQuery(); jq.executeQuery(queryString); } public void executeQuery(String qString) { Connection connection = null; // Definir propiedades de configuracin Properties props = new Properties(); props.setProperty("javax.xml.registry.queryManagerURL", "http://uddi.microsoft.com:80/inquire"); props.setProperty("javax.xml.registry.factoryClass", "com.sun.xml.registry.uddi.ConnectionFactoryImpl"); try { // Crear la conexin con las propiedades definidas ConnectionFactory factory = ConnectionFactory.newInstance(); factory.setProperties(props); connection = factory.createConnection(); // Obtener gestor de consultas RegistryService rs = connection.getRegistryService(); BusinessQueryManager bqm = rs.getBusinessQueryManager(); System.out.println("Got registry service and " + "query manager"); // Definir opciones y patrn de bsqueda

Collection findQualifiers = new ArrayList(); findQualifiers.add(FindQualifier.SORT_BY_NAME_DESC); Collection namePatterns = new ArrayList(); namePatterns.add("%" + qString + "%"); // Buscar organizaciones BulkResponse response = bqm.findOrganizations(findQualifiers, namePatterns, null, null, null, null); Collection orgs = response.getCollection(); // Mostrar informacin de las organizaciones obtenidas Iterator orgIter = orgs.iterator(); while (orgIter.hasNext()) { Organization org = (Organization) orgIter.next(); System.out.println("Org name: " + getName(org)); System.out.println("Org description: " + getDescription(org)); System.out.println("Org key id: " + getKey(org)); // Informacin de contacto User pc = org.getPrimaryContact(); if (pc != null) { PersonName pcName = pc.getPersonName(); System.out.println(" Contact name: " + pcName.getFullName()); Collection phNums = pc.getTelephoneNumbers(pc.getType()); Iterator phIter = phNums.iterator(); while (phIter.hasNext()) { TelephoneNumber num = (TelephoneNumber) phIter.next(); System.out.println(" Phone number: " + num.getNumber()); } Collection eAddrs = pc.getEmailAddresses(); Iterator eaIter = eAddrs.iterator(); while (phIter.hasNext()) { System.out.println(" Email Address: " + (EmailAddress) eaIter.next()); } } // Informacin de los servicios Collection services = org.getServices(); Iterator svcIter = services.iterator(); while (svcIter.hasNext()) { Service svc = (Service) svcIter.next(); System.out.println(" Service name: " + getName(svc)); System.out.println(" Service description: " + getDescription(svc)); Collection serviceBindings = svc.getServiceBindings(); Iterator sbIter = serviceBindings.iterator(); while (sbIter.hasNext()) { ServiceBinding sb = (ServiceBinding) sbIter.next(); System.out.println(" Binding " + "Description: " + getDescription(sb)); System.out.println(" Access URI: " + sb.getAccessURI()); } } System.out.println(" --- "); } } catch (Exception e) { e.printStackTrace(); } finally {

// Cerrar conexin if (connection != null) { try { connection.close(); } catch (JAXRException je) {} } } }

private String getName(RegistryObject ro) throws JAXRException { try { return ro.getName().getValue(); } catch (NullPointerException npe) { return ""; } } private String getDescription(RegistryObject ro) throws JAXRException { try { return ro.getDescription().getValue(); } catch (NullPointerException npe) { return ""; } } private String getKey(RegistryObject ro) throws JAXRException { try { return ro.getKey().getId(); } catch (NullPointerException npe) { return ""; } } }

JAXM
Mensajes SOAP

Un mensaje SOAP tiene la siguiente estructura: o Parte SOAP Cabecera (opcional) Cuerpo o Parte adjunta 1 (opcional, p. ej. texto plano) o Parte adjunta 2 (opcional, p. ej. una imagen)

Introduccin a JAXM

Es una API para Java que permite trabajar con mensajes SOAP sin preocuparnos de los detalles de los documentos XML que intervienen en las operaciones. Permite enviar mensajes de dos formas: o Mediante una conexin punto a punto: el programa enva el mensaje directamente al destinatario, quedando bloqueado a la espera de una respuesta. o Mediante un proveedor de mensajes: se enva el mensaje a un proveedor que ser el encargado de hacerlo llegar al destinatario, sin producirse ningn bloqueo en espera de una respuesta.

Ejemplos

El siguiente programa construye un mensaje SOAP, en el que se pregunta por el precio de cotizacin de una compaa, lo enva a un servicio de informacin de cotizaciones, y muestra el resultado obtenido:

import javax.xml.soap.*; import javax.xml.messaging.*; import java.io.*;

import java.util.*; public class Request { public static void main(String[] args) try { {

// Crear la conexin SOAPConnectionFactory scFactory = SOAPConnectionFactory.newInstance(); SOAPConnection con = scFactory.createConnection(); // Crear el mensaje MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); // Obtener componentes del mensaje SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody(); // Quitar cabecera header.detachNode(); // Aadir elemento para llamada Name bodyName = envelope.createName("GetLastTradePrice", "m", "http://wombat.ztrade.com"); SOAPBodyElement gltp = body.addBodyElement(bodyName); // Aadir elemento para dato de entrada Name name = envelope.createName("symbol"); SOAPElement symbol = gltp.addChildElement(name); symbol.addTextNode("SUNW"); // URL Destino URLEndpoint endpoint = new URLEndpoint( "http://wombat.ztrade.com/quotes"); // Envar mensaje - bloqueo - obtener respuesta SOAPMessage response = con.call(message, endpoint); /* Mensaje SOAP <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" <SOAP-ENV:Body> <m:GetLastTradePrice xmlns:m= "http://wombat.ztrade.com"> <symbol>SUNW</symbol> </m:GetLastTradePrice> </SOAP-ENV:Body> </SOAP-ENV:Envelope> */ // Cerrar la conexin con.close(); // Obtener cuerpo del mensaje SOAPPart sp = response.getSOAPPart(); SOAPEnvelope se = sp.getEnvelope(); SOAPBody sb = se.getBody(); // Obtener respuesta Iterator it = sb.getChildElements(bodyName); SOAPBodyElement bodyElement = (SOAPBodyElement)it.next(); String lastPrice = bodyElement.getValue(); // Imprimir respuesta System.out.print("The last price for SUNW is "); System.out.println(lastPrice);

} }

} catch (Exception ex) { ex.printStackTrace(); }

El siguiente programa enva un mensaje SOAP con un nombre de compaa a un registro UDDI, y muestra los datos obtenidos del registro:
import import import import javax.xml.soap.*; javax.xml.messaging.*; java.util.*; java.io.*;

public class MyUddiPing { public static void main(String[] args) { try { // Comprobar el argumento de entrada if (args.length != 1) { System.err.println("Usage: UddiPing business-name"); System.exit(1); } // Crear la conexin y el mensaje SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance(); SOAPConnection connection = scf.createConnection(); MessageFactory msgFactory = MessageFactory.newInstance(); SOAPMessage msg = msgFactory.createMessage(); // Obtener el cuerpo del mensaje SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope(); SOAPBody body = envelope.getBody(); // Aadir informacin de consulta SOAPBodyElement findBusiness = body.addBodyElement(envelope. createName("find_business", "", "urn:uddi-org:api")); findBusiness.addAttribute(envelope.createName("generic"), "1.0"); findBusiness.addAttribute(envelope.createName("maxRows"), "100"); SOAPElement businessName = findBusiness.addChildElement( envelope.createName("name")); businessName.addTextNode(args[0]); // URL destino URLEndpoint endpoint = new URLEndpoint ("http://www-3.ibm.com/services/uddi/testregistry/inquiryapi"); // Envar mensaje - bloqueo - obtener respuesta SOAPMessage reply = connection.call(msg, endpoint); // Escribir mensaje de respuesta en un fichero System.out.println("Received reply from: " + endpoint); reply.writeTo(new FileOutputStream("res.xml")); // Extraer el cuerpo SOAPBody replyBody = reply.getSOAPPart().getEnvelope().getBody(); System.out.println(""); System.out.println(""); System.out.print( "Content extracted from the reply message: "); // Mostrar informacin Iterator iter1 = replyBody.getChildElements(); while (iter1.hasNext()) { SOAPBodyElement bodyElement = (SOAPBodyElement)iter1.next(); Iterator iter2 = bodyElement.getChildElements();

while (iter2.hasNext()) { SOAPElement child2 = (SOAPElement)iter2.next(); Iterator iter3 = child2.getChildElements(); String content = child2.getValue(); System.out.println(content); while (iter3.hasNext()) { SOAPElement child3 = (SOAPElement)iter3.next(); Iterator iter4 = child3.getChildElements(); content = child3.getValue(); System.out.println(content); while (iter4.hasNext()) { SOAPElement child4 = (SOAPElement)iter4.next(); content = child4.getValue(); System.out.println(content); } } } } // Cerrar la conexin connection.close(); } catch (Exception ex) { ex.printStackTrace(); }

} }

JAX-RPC
Introduccin

Es una API para Java que permite construir servicios web y clientes para los servicios sin preocuparnos de los detalles de los documentos XML que intervienen en las operaciones. Las llamadas a los mtodos y las respuestas se implementan mediante mensajes SOAP. En un servicio web, los mtodos que lo constituyen se definen en un interfaz y se implementan en una clase aparte. En un cliente, las llamadas a los mtodos se realizan mediante objetos locales que representan el mtodo remoto (stubs). Un cliente escrito con JAX-RPC puede interactuar con un servicio escrito en otro lenguaje, y viceversa, pues esta tecnologa se basa en una serie de estndares como HTTP, SOAP y WSDL.

Un ejemplo

A continuacin se muestra un sencillo ejemplo de servicio con un cliente que lo utiliza:

package SR; import java.rmi.Remote; import java.rmi.RemoteException; public interface SRInt extends Remote { public int suma(int a, int b) throws RemoteException; public int resta(int a, int b) throws RemoteException; } package SR; public class SRImpl implements SRInt { public int suma(int a, int b) {

return a + b;

public int resta(int a, int b) { return a - b; } } package SR; public class SRClient { public static void main(String[] args) { try { SRInt_Stub stub = (SRInt_Stub)(new ServicioSRImpl().getSRInt()); stub._setTargetEndpoint(args[0]); System.out.println(stub.suma(3, 8)); System.out.println(stub.resta(23, 8)); } catch (Exception ex) { ex.printStackTrace(); } } }

Apuntes de XML
Autor: Diego Arranz Hernando

Bibliografa recomendada o En ingls o En castellano

Bibliografa recomendada
En ingls
Java & XML, 2nd Edition: Solutions to Real-World Problems OReilly Brett McLaughlin Septiembre 2001 Modeling XML Applications with UML Addison Wesley David Carlson Abril 2001

En castellano
Java y XML Anaya OReilly Brett McLaughlin 2001 Gua de aprendizaje XML Prentice Hall Elizabeth Castro 2001

Apuntes de XML
Autor: Diego Arranz Hernando

Enlaces recomendados o Generales o Introduccin o Creacin de documentos XML o Restriccin de documentos XML o Presentacin y transformacin de documentos XML o Manipulacin de XML desde programas Java o XML y las bases de datos o Otros temas de inters o Servicios web

Enlaces recomendados
Generales

ltimas noticias sobre XML (ingls) Enlaces a software XML (ingls) Java y XML (ingls) Proyecto colaborativo Apache XML (ingls) XML en Microsoft (ingls) Diseo de aplicaciones XML con UML (ingls)

Introduccin

XML en 10 puntos Breve tutorial de ngel Barbero FAQ sobre XML (ingls) Motivacin del XML (ingls)

Creacin de documentos XML



Especificacin XML en castellano Especificacin XML comentada (ingls) Sencillo editor XML (ingls) Completo editor XML con innumerables opciones (ingls)

Restriccin de documentos XML



Tutorial sobre DTD Otro tutorial sobre DTD (ingls) Tutorial sobre esquemas XML (ingls) Completsimo curso sobre esquemas XML en transparencias (ingls)

Presentacin y transformacin de documentos XML



Uso de CSS con XML Ms sobre uso de CSS con XML Documentacin de Microsoft, sobre XSLT, Xpath, etc. Tutorial sobre XSLT con numerosos ejemplos (ingls)

Tutorial sobre XSLT y Xpath (ingls) Especificacin XPath en castellano

Manipulacin de XML desde programas Java



Tutorial traducido del sitio oficial de Sun, sobre SAX, DOM, XML, DTD, etc. Pgina de SAX (ingls) Pgina de DOM en el W3C (ingls) Pgina del analizador Xerces (ingls) Pgina del procesador (XSLT) Xalan (ingls)

XML y las bases de datos



APIs y herramientas de conversin (ingls) Bases de datos nativas XML (ingls)

Otros temas de inters



XLink (ingls) JDOM (ingls) Tutorial sobre Cocoon Pgina de Cocoon (ingls)

Servicios web

Noticias y artculos Java y servicios web

Apuntes de XML
Autor: Diego Arranz Hernando

Material utilizado o Bibliografa o Enlaces o Herramientas

Material utilizado
Bibliografa
Java y XML Anaya OReilly Brett McLaughlin 2001 Gua de aprendizaje XML Prentice Hall Elizabeth Castro 2001

Enlaces

Tutorial traducido del sitio oficial de Sun, sobre SAX, DOM, XML, DTD, etc. Curso sobre esquemas XML de Roger L. Costello XML en Microsoft Tutorial sobre XLink Pgina de JDOM Tutorial sobre Cocoon Tutorial de Sun sobre servicios web

Herramientas

XMLSpy 4.3 (versin de evaluacin) JDK 1.4 Xerces (Apache) JWSDP EA1

Apuntes de XML
Autor: Diego Arranz Hernando

Ejercicios o Creacin de documentos XML Enunciado Solucin o DTDs Enunciado Solucin o Esquemas XML Enunciado Solucin o XSLT Enunciado Solucin o SAX Enunciado Solucin o DOM Enunciado Solucin o DOM (otro) Enunciado Solucin

Ejercicios
Creacin de documentos XML
Enunciado
Construir un documento XML para el siguiente pedido que ha recibido por correo electrnico una empresa que se dedica a la venta de herramientas para jardinera: "Hola, necesito una cortadora de cesped para mi jardn de esas que anuncian en oferta, me gustara que fuera uno de esos modelos elctricos, pues las de gasolina contaminan mucho. Me llamo Roberto Movilla, la cortadora la tendrn que enviar a Albacete, la direccin es Plaza de la Duquesa 12, la recoger mi esposa que se llama Alicia Abad. Ahora que lo pienso tambin necesitar 3 podadoras para los setos. Les paso mi direccin de aqu para lo referente al pago, es General Ricardos 56, aqu en Madrid. Es urgente, por favor, el csped est muy alto." La fecha del pedido es el 20 de octubre del 99. El empleado que se encarga del pedido ha comprobado algunos datos necesarios: el cdigo postal de la direccin de Albacete es 05020 y el de la de Madrid 28055; tambin ha consultado el catlogo de productos y ha averiguado que la cortadora vale 148.95 euros y su cdigo de producto es 872-AA, aunque no sabe si es o no elctrica; una podadora vale 7.98 y su cdigo es 926-FH.

Solucin
<?xml version="1.0" encoding="ISO-8859-1"?> <Pedido xmlns="http://www.miempresa.org/pedidos" fecha="1999-10-20"> <Destino> <Nombre>Alicia Abad</Nombre> <Direccion>Plaza de la Duquesa 12</Direccion>

<Ciudad>Albacete</Ciudad> <CodPostal>05020</CodPostal> </Destino> <Ordenante> <Nombre>Roberto Movilla</Nombre> <Direccion>General Ricardos 56</Direccion> <Ciudad>Madrid</Ciudad> <CodPostal>28055</CodPostal> </Ordenante> <Observaciones>Es urgente, el csped est muy alto</Observaciones> <Contenido> <Producto codigo="872-AA"> <Nombre>Cortadora de cesped</Nombre> <Cantidad>1</Cantidad> <Precio>148.95</Precio> <Observaciones>Confirmar que es elctrica</Observaciones> </Producto> <Producto codigo="926-FH"> <Nombre>Podadora</Nombre> <Cantidad>3</Cantidad> <Precio>7.98</Precio> </Producto> </Contenido> </Pedido>

DTDs
Enunciado
Construir un documento DTD para el documento XML del ejercicio anterior.

Solucin
<!DOCTYPE Pedido SYSTEM "Pedido.dtd"> ... <!ELEMENT Pedido (Destino, Ordenante, Observaciones, Contenido)> <!ATTLIST Pedido xmlns CDATA #REQUIRED fecha CDATA #REQUIRED > <!ELEMENT Destino (Nombre, Direccion, Ciudad, CodPostal)> <!ELEMENT Ordenante (Nombre, Direccion, Ciudad, CodPostal)> <!ELEMENT Nombre (#PCDATA)> <!ELEMENT Direccion (#PCDATA)> <!ELEMENT Ciudad (#PCDATA)> <!ELEMENT CodPostal (#PCDATA)> <!ELEMENT Observaciones (#PCDATA)> <!ELEMENT Contenido (Producto+)> <!ELEMENT Producto (Nombre, Cantidad, Precio, Observaciones?)> <!ATTLIST Producto codigo CDATA #REQUIRED > <!ELEMENT Cantidad (#PCDATA)> <!ELEMENT Precio (#PCDATA)>

Esquemas XML
Enunciado
Construir un esquema XML para la siguiente DTD:
<!ELEMENT Libro (Titulo, Contenido, Copyright)> <!ATTLIST Libro xmlns CDATA #REQUIRED >

<!ELEMENT Titulo (#PCDATA)> <!ELEMENT Contenido ((Capitulo+, Separacion?)+)> <!ELEMENT Capitulo (Tema, Seccion+)> <!ATTLIST Capitulo materia (XML|Java) "Java" > <!ELEMENT Tema (#PCDATA)> <!ELEMENT Seccion (#PCDATA)> <!ATTLIST Seccion apartados CDATA #REQUIRED dificil (si|no) "no" > <!ELEMENT Separacion EMPTY> <!ELEMENT Copyright (#PCDATA)>

y probarlo con este documento:


<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <!DOCTYPE Libro [ <!ENTITY OReillyCopyright SYSTEM "copyright.txt"> ]> <Libro xmlns="http://www.mislibros.com/libros/javaxml" xmlns:Catalogo="http://www.mislibros.com/catalogo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mislibros.com/libros/javaxml libro.xsd"> <Titulo>Java y XML</Titulo> <Contenido> <Capitulo materia="XML"> <Tema>Introduccin</Tema> <Seccion apartados="7">Qu es</Seccion> <Seccion apartados="3">Cmo se usa</Seccion> </Capitulo> <Capitulo materia="XML"> <Tema>Creando XML</Tema> <Seccion apartados="0">Un documento XML</Seccion> <Seccion apartados="2">La cabecera</Seccion> <Seccion apartados="6">El contenido</Seccion> </Capitulo> <Capitulo> <Tema>Analizando XML</Tema> <Seccion apartados="3">Preparacin</Seccion> <Seccion apartados="3" dificil="true">SAX</Seccion> <Seccion apartados="9" dificil="true">Manejadores</Seccion> <Seccion apartados="0">Una forma mejor de cargar el analizador</Seccion> </Capitulo> <Separacion/> <Capitulo materia="Java"> <Tema>JDOM</Tema> <Seccion apartados="2">Introduccin</Seccion> <Seccion apartados="4" dificil="true">DOM&amp;JDOM</Seccion> </Capitulo> </Contenido> <Copyright>&OReillyCopyright;</Copyright> </Libro>

Solucin
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

targetNamespace="http://www.mislibros.com/libros/javaxml" xmlns="http://www.mislibros.com/libros/javaxml" elementFormDefault="qualified"> <xs:element name="Libro" type="TipoLibro"/> <xs:complexType name="TipoLibro"> <xs:sequence> <xs:element name="Titulo" type="xs:string"/> <xs:element name="Contenido" type="TipoContenido"/> <xs:element name="Copyright" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="TipoContenido"> <xs:sequence maxOccurs="unbounded"> <xs:element name="Capitulo" type="TipoCapitulo" maxOccurs="unbounded"/> <xs:element name="Separacion" type="TipoVacio" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="TipoCapitulo"> <xs:sequence> <xs:element name="Tema" type="xs:string"/> <xs:element name="Seccion" type="TipoSeccion" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="materia" type="TipoMateria" default="Java"/> </xs:complexType> <xs:complexType name="TipoSeccion"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="apartados" type="xs:nonNegativeInteger" use="required"/> <xs:attribute name="dificil" type="xs:boolean" default="false"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:simpleType name="TipoMateria"> <xs:restriction base="xs:string"> <xs:enumeration value="Java"/> <xs:enumeration value="XML"/> </xs:restriction> </xs:simpleType> <xs:complexType name="TipoVacio"/> </xs:schema>

XSLT
Enunciado
A partir del siguiente documento XML, realizar una hoja de estilo XSLT que muestre los datos en una tabla, con las siguientes caractersticas: las empresas aparecen ordenadas por el precio de cotizacin, los precios supreriores a 75 aparecen en azul y los inferiores a 25 en rojo, las empresas del ndice general aparecen marcadas con un (*), con una explicacin debajo de la tabla. El ttulo del documento refleja el da y hora de la informacin.
<?xml version="1.0" ?> <Bolsa xmlns="http://www.labolsa.com" dia="5-7-2001" hora="11:34"> <Empresa indice="general"> <Nombre>General Motors</Nombre> <Simbolo>GMO</Simbolo> <Precio>28.875</Precio> </Empresa> <Empresa indice="tecno"> <Nombre>Adobe</Nombre>

<Simbolo>ADB</Simbolo> <Precio>92.250</Precio> </Empresa> <Empresa indice="tecno"> <Nombre>Microsoft</Nombre> <Simbolo>MSF</Simbolo> <Precio>20.313</Precio> </Empresa> <Empresa indice="general"> <Nombre>Coca-Cola</Nombre> <Simbolo>COC</Simbolo> <Precio>38.895</Precio> </Empresa> <Empresa indice="tecno"> <Nombre>Sun Microsystems</Nombre> <Simbolo>SUN</Simbolo> <Precio>45.119</Precio> </Empresa> </Bolsa>

Solucin
<?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:Bolsa="http://www.labolsa.com" version="1.0"> <xsl:template match="Bolsa:Bolsa"> <html> <head> <title>La bolsa el <xsl:value-of select="@dia" /> a las <xsl:value-of select="@hora" /></title> </head> <body> <table border="2" align="center"> <tr> <th>Smbolo</th> <th>Nombre</th> <th>Precio</th> </tr> <xsl:for-each select="Bolsa:Empresa"> <xsl:sort select="Bolsa:Precio" order="descending"/> <tr> <td> <xsl:value-of select="Bolsa:Simbolo"/> </td> <td> <xsl:value-of select="Bolsa:Nombre"/> <xsl:if test="@indice='general'"> (*)</xsl:if> </td> <td> <xsl:choose> <xsl:when test="Bolsa:Precio &gt; 75"> <font color="blue"><xsl:value-of select="Bolsa:Precio"/></font> </xsl:when> <xsl:when test="Bolsa:Precio &lt; 25"> <font color="red"><xsl:value-of select="Bolsa:Precio"/></font> </xsl:when> <xsl:otherwise> <xsl:value-of select="Bolsa:Precio"/> </xsl:otherwise> </xsl:choose> </td> </tr> </xsl:for-each> </table> <p align="center">(*) Estas empresas son del ndice general</p> </body> </html> </xsl:template>

</xsl:stylesheet>

SAX
Enunciado
Realizar mediante SAX un programa para el documento del libro. El programa debe escribir en un fichero los ttulos de los captulos y un pequeo resumen para cada uno de ellos con el nmero de secciones, de apartados totales y de apartados difciles.

Solucin
import import import import import import import import java.io.IOException; java.io.FileWriter; org.xml.sax.SAXException; org.xml.sax.XMLReader; org.xml.sax.Attributes; org.xml.sax.ContentHandler; org.xml.sax.Locator; org.xml.sax.helpers.XMLReaderFactory;

public class EjercicioSAX { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Analizando: " + fich + "\n"); try { XMLReader parser = XMLReaderFactory.createXMLReader( "org.apache.xerces.parsers.SAXParser"); ManejadorCaps man = new ManejadorCaps(); parser.setContentHandler(man); parser.parse(fich); System.out.println("Fin del anlisis. Todo bien\n"); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } } } } class ManejadorCaps implements ContentHandler { private private private private private private Locator loc; FileWriter f; boolean extraer; int numSecciones; int numApartados; int numDificiles;

public void setDocumentLocator(Locator l) { loc = l; } public void startDocument() throws SAXException { try { numSecciones = 0; numApartados = 0; numDificiles = 0; f = new FileWriter("capitulos.txt"); } catch (IOException e) {

} }

throw new SAXException ("Problemas al abrir fichero");

public void endDocument() throws SAXException { try { f.close(); } catch (IOException e) { throw new SAXException ("Problemas al cerrar fichero"); } } public void startElement(String espacio, String nomLocal, String nomCompleto, Attributes atrs) { if (nomLocal.equals("Tema")) { extraer = true; } else if (nomCompleto.equals("Seccion")) { numSecciones++; numApartados += Integer.parseInt(atrs.getValue(0)); if (atrs.getValue(1).equals("si")) { numDificiles++; } } } public void endElement(String espacio, String nomLocal, String nomCompleto) throws SAXException { if (nomLocal.equals("Tema")) { extraer = false; } else if (nomLocal.equals("Capitulo")) { try { f.write("\t" + numSecciones + " secciones\r\n" + "\t" + numApartados + " apartados\r\n" + "\t(" + numDificiles + " difciles)\r\n"); numSecciones = 0; numApartados = 0; numDificiles = 0; } catch (IOException e) { throw new SAXException ("Problemas al escribir en fichero"); } } } public void characters(char[] ch, int comienzo, int fin) throws SAXException { try { if (extraer) { String tema = new String(ch, comienzo, fin); f.write(tema + "\r\n"); } } catch (IOException e) { throw new SAXException ("Problemas al escribir en fichero"); } } public void processingInstruction(String destino, String datos) { } public void startPrefixMapping(String prefijo, String uri) { } public void endPrefixMapping(String prefijo) { } public void ignorableWhitespace(char[] ch, int comienzo, int fin) { }

public void skippedEntity(String nombre) { } }

DOM
Enunciado
Realizar mediante DOM un programa para el documento del libro. El programa debe escribir en un fichero los ttulos de los captulos y un pequeo resumen para cada uno de ellos con el nmero de secciones, de apartados totales y de apartados difciles.

Solucin
import import import import import import import import import org.w3c.dom.Document; org.w3c.dom.Node; org.w3c.dom.Element; org.w3c.dom.NodeList; org.w3c.dom.NamedNodeMap; java.io.IOException; org.xml.sax.SAXException; org.apache.xerces.parsers.DOMParser; java.io.FileWriter;

public class EjercicioDOM { static static static static FileWriter f; int numSecciones; int numApartados; int numDificiles;

public static void procesar(Node nodo) throws IOException { Element e = (Element)nodo; String nombre = e.getNodeName(); if (nombre.equals("Libro")) { f = new FileWriter("capitulosDOM.txt"); NodeList hijos = e.getElementsByTagName("Capitulo"); for (int i=0; i<hijos.getLength(); i++) { procesar(hijos.item(i)); } f.close(); } else if (nombre.equals("Capitulo")) { procesar(e.getElementsByTagName("Tema").item(0)); NodeList hijos = e.getElementsByTagName("Seccion"); numSecciones = hijos.getLength(); numApartados = 0; numDificiles = 0; for (int i=0; i<hijos.getLength(); i++) { procesar(hijos.item(i)); } f.write("\tSecciones: " + numSecciones + "\r\n"); f.write("\tApartados: " + numApartados + "\r\n"); f.write("\t(Difciles: " + numDificiles + ")\r\n"); } else if (nombre.equals("Tema")) { f.write(e.getFirstChild().getNodeValue() + "\r\n"); } else if (nombre.equals("Seccion")) { numApartados += Integer.parseInt(e.getAttribute("apartados")); if (e.getAttribute("dificil").equals("si")) { numDificiles++; } }

public static void main(String[] args) { if (args.length != 1) {

System.out.println("Debe haber un parmetro (el fichero)"); } else { String fich = args[0]; System.out.println("Generando rbol para: " + fich + "\n"); try { DOMParser parser = new DOMParser(); parser.parse(fich); Document doc = parser.getDocument(); procesar(doc.getDocumentElement()); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } } } }

DOM (otro)
Enunciado
Realizar mediante DOM un programa a partir de un documento con las notas detalladas de una serie de alumnos de una clase. El programa debe imprimir por pantalla la media de cada alumno y la media total de la clase, as como generar un documento XML con esta informacin. Entrada
<?xml version="1.0"?> <course> <teacher id="jp"> <name>John Punin</name> </teacher> <student id="js"> <name>John Smith</name> <hw1>30</hw1> <hw2>70</hw2> <project>80</project> <final>85</final> </student> <student id="gl"> <name>George Lucas</name> <hw1>80</hw1> <hw2>90</hw2> <project>100</project> <final>40</final> </student> <student id="lr"> <name>Elizabeth Roberts</name> <hw1>60</hw1> <hw2>95</hw2> <project>50</project> <final>100</final> </student> </course>

Salida
Alumno John Smith = 66.25 Alumno George Lucas = 77.5 Alumno Elizabeth Roberts = 76.25 Media de la clase = 73.333336 <?xml version="1.0" encoding="UTF-8"?> <Notas Media="73.333336"> <Alumno> <Nombre>John Smith</Nombre> <Nota>66.25</Nota> </Alumno> <Alumno>

<Nombre>George Lucas</Nombre> <Nota>77.5</Nota> </Alumno> <Alumno> <Nombre>Elizabeth Roberts</Nombre> <Nota>76.25</Nota> </Alumno> </Notas>

Solucin
import import import import import org.w3c.dom.*; javax.xml.parsers.*; org.apache.xerces.dom.DocumentImpl; org.apache.xml.serialize.*; java.io.*;

public class OtroEjDOM { static float notas[][] = new float[100][5]; static String nombres[] = new String[100]; public static void main(String[] args) { try { DocumentBuilder parser; DocumentBuilderFactory factoria = DocumentBuilderFactory.newInstance(); parser = factoria.newDocumentBuilder(); Document doc = parser.parse(args[0]); NodeList studs = doc.getElementsByTagName("student"); for (int i=0; i<studs.getLength(); i++) { tratarStud((Element) studs.item(i), i); } calcularNotas(studs.getLength()); } catch (Exception e) { e.printStackTrace(System.err); }

private static void tratarStud(Element elemStud, int numStud) { nombres[numStud] = extraerValor(elemStud, "name"); notas[numStud][0] = Integer.parseInt(extraerValor(elemStud, notas[numStud][1] = Integer.parseInt(extraerValor(elemStud, notas[numStud][2] = Integer.parseInt(extraerValor(elemStud, notas[numStud][3] = Integer.parseInt(extraerValor(elemStud, } private static String extraerValor(Element elem, String campo) { Element subElem = (Element) elem.getElementsByTagName(campo).item(0); return subElem.getFirstChild().getNodeValue(); } private static void calcularNotas(int numStuds) { float media = 0; int i = 0, j = 0; System.out.println(); for(i = 0; i < numStuds ; i++) { float total = 0; for(j = 0; j < 4; j++) { total += notas[i][j]; } notas[i][4] = total/4; media += notas[i][4]; System.out.println("Alumno " + nombres[i] + " = " + notas[i][4]); } media /= numStuds; System.out.println("Media de la clase = " + media); "hw1")); "hw2")); "project")); "final"));

System.out.println(); try { Document doc= new DocumentImpl(); Element raiz = doc.createElement("Notas"); raiz.setAttribute("Media", String.valueOf(media)); for(i = 0; i < numStuds ; i++) { Element alumno = doc.createElement("Alumno"); Element nombre = doc.createElement("Nombre"); nombre.appendChild(doc.createTextNode(nombres[i])); alumno.appendChild(nombre); Element nota = doc.createElement("Nota"); nota.appendChild(doc.createTextNode(String.valueOf(notas[i][4]))); alumno.appendChild(nota); raiz.appendChild(alumno); } doc.appendChild(raiz); OutputFormat formato = new OutputFormat(doc, "UTF-8", true); StringWriter s = new StringWriter(); XMLSerializer ser = new XMLSerializer(s, formato); ser.serialize(doc); System.out.println(s.toString()); FileWriter f = new FileWriter("notas.xml"); ser = new XMLSerializer(f, formato); ser.serialize(doc); } catch (IOException e) { System.out.println(e); }

} }

También podría gustarte