Interacción entre Aplicaciones: XML

Documentos relacionados
Interacción entre Aplicaciones: XML

FSD Práctica XML, SAX, DOM y JDOM. Introducción

SAX. cómo funciona? Introducción. La API de análisis basada en eventos

3.3 Parsers SAX con JAXP

Procesamiento de documentos XML

Interacción entre Aplicaciones con xml: Intercambio de documentos e invocación remota

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Procesamiento de documentos XML.

XML, Servicios Web y Web Semántica

Introducción a Java LSUB. 30 de enero de 2013 GSYC

Variables. Una variable no es más que un nombre simbólico que identifica una dirección de memoria: vs.

James Gosling, creador de Java

Carlos Montenegro. Programación Orientada a Objetos Proyecto Curricular de Ingeniería de Sistemas

1. Cuántas sentencias hay en la secuencia principal del siguiente programa?

2. Estructura de un programa en Java

Java RMI Remote Method Invocation. Invocación Remota de Métodos en Java

Conceptos a tratar. Fundamentos de la Programación Orientada a Objetos Ampliación sobre clases y objetos

Centro Asociado Palma de Mallorca. Antonio Rivero Cuesta

6.1 APIs para XML. APIs para XML (I) ! Uno de los usos más habituales de XML (y menos esperado) es como formato de intercambio de datos.

Java RMI. las RPC de Java. Parte I. Luis Fernando Llana Díaz. Departamento de Sistemas Informáticos y ProgramaciónUniversidad Complutense de Madrid

Ejercicios de Programación Tema 7. Programación Orientada a Objetos

Curso JAVA EE

Introducción a Java LSUB. 15 de enero de 2015 GSYC

Introducción a Java (II) Dr. (c) Noé Alejandro Castro Sánchez

DISEÑO DE UNA ARQUITECTURA CLIENTE/SERVIDOR MEDIANTE OBJETOS DISTRIBUIDOS EN JAVA

Tema 15: Aserciones 0

SAX Parser. Ing. Augusto Dobeslao Herández López (Bases de Datos en XML)

PHP 7 Desarrollar un sitio web dinámico e interactivo

Sistemas Distribuidos Java RMI (Remote Method Invocation) Alberto Lafuente Mikel Larrea Dpto. ATC, UPV/EHU

Java RMI. Sistemas Distribuidos Rodrigo Santamaría

Construcciones del Lenguaje Java

Universidad Autónoma de Tlaxcala. M.C. José Juan Hernández Mora. Primera Sesión

2) Cual modificador limita el acceso a un método de una clase pública a los miembros de la misma clase?

Clase adicional 9. Listas enlazadas. Temas. Listas enlazadas Árboles Problemas de la clase adicional Ejercicios de diseño

Modelo de Objetos Distribuidos

Objetivo de aprendizaje del tema

Tecnología XML. Unidad: 3 Laboratorio de Programación. Universidad Nacional de la Patagonia Austral Unidad Académica Río Gallegos

ÍNDICE CAPÍTULO I AGRADECIMIENTO DEDICATORIA. Página

Elementos léxicos del lenguaje de programación Java

Primer Parcial Septiembre 5 de 2009

Visualización y Transformaciones en XML

Tema 7.- Fundamentos de la Programación Orientada a Objetos

Práctica 2: Java Remote Method Invocation (RMI)

PROCESADORES DE LENGUAJES I PRÁCTICA DE LABORATORIO 4

- Compilar y ejecutar programas en Java - Estructura básica de una clase - El comando javac - El comando java - Introducción al IDE de desarrollo

Lo que necesitaremos para programar en Java, será un editor de texto o IDE y la JDK.

CONCEPTOS BASICOS DEL LENGUAJE JAVA

PROGRAMACION DISTRIBUIDA

OpenSAMLPerl. Descripción Y Guía de Usuario. Daniel García Franco 17 de enero de Estructura de OpenSAMLPerl 2

PROGRAMACION DISTRIBUIDA MobileTracker: Ejemplo de implementación con RMI

2.2 Parsing de documentos XML

Por el contrario System.in es un byte Stream sin caracteristicas de character Stream.

Interacción y manejo de documentos XML.

Especificaciones del driver JDBC

Identificadores, palabras reservadas, tipos de datos, operadores aritméticos y el sistema estándar de salida en Java

Tema: Estructuras de Selección en C#.

Práctica 7: Invocación Web Services con REST

Programa Java. El lenguaje de programación Java. Comentarios. Programa Java. Palabras reservadas. Identificadores

Práctica III: Streams, Readers y Writers

FSD Práctica Invocación Remota: JavaRMI. Estudio Previo. Información

JavaScript. Contenidos. Introducción El lenguaje Validación de formularios. Programación en Internet DLSI - Universidad de Alicante 1

EXAMEN PROGRAMACIÓN 21 de Septiembre de 2007 INGENIERÍA INFORMÁTICA Primera parte: Cuestiones 1,5 horas

Tema 4. Excepciones en Java

1. Visión general de RMI

Java en 2 horas. Rodrigo Santamaría

INDICE DEL CURSO APRENDER PROGRAMACIÓN JAVA DESDE CERO. PROGRAMACIÓN ORIENTADA A OBJETOS (CU00601B)

Java en 3 horas. Ampliación de Sistemas Operativos. Rodrigo Santamaría

FACULTAD DE INGENIERÍA

Definición. Mónica E. García García Feb 07

JAVA RMI (REMOTE METHOD INVOCATION)

Sockets en Java. Prof. Wílmer Pereira Universidad Simón Bolívar

Roberto Gómez Cárdenas Qué es DOM?

FUNDAMENTOS DE PROGRAMACIÓN. SEPTIEMBRE 2005

FRAMEWORK 2 Recepción de SMS

Interacción entre Aplicaciones: objetos distribuidos e invocación remota

Solución al Examen de Prácticas de Programación (Ingeniería Informática)

StringBuffer, Math y Wrapper

Bibliografía (Java) Java: Introducción a Java

LA ESTRUCTURA DE DATOS PILA EN JAVA. CLASE STACK DEL API JAVA. EJEMPLO Y EJERCICIOS RESUELTOS. (CU00923C)

Unidad II. Fundamentos de programación en Java. Ing. José Luis Llamas Cárdenas

1.2. Es Java un lenguaje ideal para aprender a programar? 1.4. Cuáles son las versiones y distribuciones Java y cuál usar?

Elementos del lenguaje Java

Clases. Java: Clases y Objetos. Clases. Clases. Modificadores de clase. Definición de una clase. Cada objeto es un ejemplar de una clase

Arquitecturas cliente/servidor

Manual del Protocolo XML-RPC de Mensajería Negocios

Prueba N o 1. Programación II

class Nombre_Clase extends Nombre_SuperClase { cuerpo de la clase extendida }

Práctica 4 PROGRAMACIÓN WEB CON SERVLETS Y JSP. 1. Introducción a JSP... 2

UNIVERSIDAD DE SEVILLA PRÁCTICAS DE LABORATORIO ANÁLISIS SINTÁCTICO (1) LENGUAJES FORMALES Y AUTÓMATAS CURSO 2006/2007

Arquitectura Cliente/Servidor. Invocación de Métodos Remotos RMI: Remote Method Invocation. Llamadas a Métodos Remotos

3.3 Conceptos Básicos del Lenguaje Java

Clase adicional 2. Estructuras básicas de control. Temas

Experto Universitario Java Enterprise Spring

Programación Orientada a Objetos. Resumen de Temas Unidad 3: Constructores y destructores

Metodología y Tecnología de la Programación

Programación Orientada a Objetos. Java: Excepciones

Diferentes Perspectivas de un Ordenador

en otra máquina exactamente de la misma manera que si se encontrará en la misma máquina

Llamada a métodos remotos (RMI). Curso 04/05. Tema 9. Departament d Informàtica. Universitat de València. 1. Introducción 2

Curso Introducción JAVA Pág.: 1

Transcripción:

Interacción entre Aplicaciones: XML En esta práctica se va a conocer y experimentar con la manipulación de documentos XML y las herramientas que hay disponibles. Muchas aplicaciones utilizan XML para varios propósitos: Presentación: la separación entre contenido, los datos, y presentación, el formato de los datos. Por ejemplo los datos de una reserva de avión se han de presentar en html para un cliente web, en WML o XHTML para un dispositivo móvil, o en PDF si se va a imprimir. Por ejemplo, en la construcción de clientes y servidores Web que usen XML (como cocoon, enhydra, caucho, bluestone, saxon) que transforman en función del cliente xml xml+xsl xhtml wml pdf. Comunicación: entre aplicaciones sin que el formato esté ligado a ninguna presentación. En muchas ocasiones comunidades de organizaciones o empresas de un cierto sector definen un vocabulario XML común para la interacción entre todos ellos de documentos como pedidos, facturas, etc. (ebusiness) Interacción: intercambio de documentos XML en forma de llamada a función remota como XML- RPC o SOAP en que dos componentes intercambian documentos XML que invocan una operación remota. Configuración: para guardar datos de configuración de las aplicaciones, como hace Apache, Tomcat o Enterprise Java Beans (EJB), o para guardar los datos de cualquier aplicación. Aplicación Doc 1.xml dato Anlz 1 dato 1 Anlz Doc. Doc. Análisis dato XML 2 dato 2 Emisión XML' dato Datos Doc 2.xml Datos 3 dato 3 Aplicación 1 Aplicación 2 Fig 1.- Usos de XML: 1.a) configuración, transformación; 1.b) intercambio entre aplicaciones. La buena noticia, si se trabaja con información representada en xml, es que abundan las herramientas para analizar texto xml y acceder, tratar, transformar los datos que contiene. Para ello se utilizan componentes que suelen ofrecen uno o los 2 API estandarizados: SAX y DOM. Si se utiliza uno de estos API, el código que utiliza un analizador no cambia si se sustituue el componente que procesa documentos XML. Un analizador XML ofrece los servicios de serializar y deserializar documentos XML, entre la forma serie (textual) y la forma no serie seleccionada por el programador: una estructura de datos o un conjunto de llamadas a métodos, uno por cada componente del documento. Estos mecanismos de serialización y deserialización se utilizan también para construir RPC con datos en XML sobre transporte HTTP. Análisis: deserialización Doc XML serialización dato 1 dato 2 dato 3 Fig 2.- procesos que realiza un analizador Se va a utilizar el analizador XercesJ_1_2, disponible en C, perl y Java y hecho público por IBM bajo licencia Apache. Se puede encontrar en http://xml.apache.org (y para facilitar el acceso, una copia en el web del laboratorio de aad) Los API más habituales son: SAX (Simple API for XML) funciona por eventos y métodos asociados. A medida que el analizador va leyendo el documento xml y encuentra (los eventos) los componentes del documento 1

(elementos, atributos, valores, etc) o detecta errores, va invocando a las funciones que ha asociado el programador. Más información de SAX en http://www.megginson.com/sax DOM (Document Object Model) Mientras que SAX ofrece acceso a cada trozo del documento xml tal como se va leyendo, DOM proporciona una representación de un documento XML en forma de árbol. El árbol se puede recorrer y transformar. El principal inconveniente es también el árbol: 1) sólo se accede a los datos una vez se han leído todos, y 2) el árbol es un objeto cargado en memoria; esto es problemático para documentos grandes y complejos. Más información de DOM en http://www.w3.org/dom SAX evento i método i ().xml árbol DOM Fig 3.- JDOM: un API para leer, escribir, crear y manipular XML cómodamente desde Java. Al ser un API específico para Java es mucho más intuitivo y sencillo que los anteriores, pero no está pensado para otros lenguajes. Más información de JDOM en http://www.jdom.org Los analizadores se pueden adaptar y seleccionar diferentes opciones, entre ellas si ha de comprobarse o no la validez de un documento xml respecto a su definición (el DTD). Esta validación añade una comprobación y por tanto una garantía más, pero también consume más recursos y ralentiza el procesamiento del documento xml. En cada situación habrá que valorar qué opciones son adecuadas. Validación dato Documento Análisis dato XML dato Fig. 4.- Los analizadores pueden también validar el documento xml. Las aplicaciones que se basan en la transformación de documentos XML, también pueden recurrir a un procesador para transformar documentos XML según las reglas e instrucciones de XSLT, de forma que la transformación de un documento XML se rige por una hoja de estilo XSL (que también es un documento XML), en lugar de escribir un programa que lo haga. Esto queda fuera del ámbito de esta práctica..dtd.xsl Motor.xml.??? XSLT Fig. 5: XSLT. Análisis de XML con SAX y DOM Un programa sencillo va a contar el número de elementos y atributos de un documento xml. Con SAX: 1) Instanciar un "lector" que implemente el interface org.xml.sax.xml-reader, que en Xerces es la clase org.apache.xerces.parsers.saxparser; invocar el método parse para que analice el documento pasado como argumento del programa. import org.xml.sax.xmlreader; import org.apache.xerces.parsers.saxparser; public class SAXParserMin { public static void main(string [] args) { if (args.length!= 1) { System.out.println("Uso: java SAXParserMin url"); 2

System.exit(0); XMLReader parser = new SAXParser(); parser.parse(url); Si el programa funciona, quiere decir que java y xerces están bien instalados. Sin embargo el programa no hace nada pues no hemos registrado interés en ningún evento durante el análisis. Dado que el documento a analizar puede fallar durante la transferencia o ser incorrecto, es conveniente capturar las excepciones java.io.ioexception y org.xml.sax.saxexception al invocar al método parse. Gestores de Contenido Hay cuatro interfaces o familias de funciones que se pueden asociar a eventos: org.xml.sax.contenthandler: eventos sobre datos (el principal y el más extenso), org.xml.sax.errorhandler: eventos sobre errores, org.xml.sax.dtdhandler: tratamiento de DTDs y por último org.xml.sax.entityresolver: entidades externas. Se pueden definir clases con los métodos necesarios para tratar cada evento que nos interese. Para detectar: datos: implementar el interface org.xml.sax.contenthandler, y registrarse en el analizador con el método setcontenthandler(). errores: implementar el interface org.xml.sax.errorhandler, y registrarse en el analizador con el método seterrorhandler(). Veamos a continuación un ejemplo de analizador SAX que utiliza xerces y que cuenta los elementos, atributos y blancos que aparecen en un documento xml: package sax; import java.io.outputstreamwriter; import java.io.printwriter; import java.io.unsupportedencodingexception; import org.xml.sax.attributes; import org.xml.sax.saxexception; import org.xml.sax.saxparseexception; import org.xml.sax.xmlreader; import org.xml.sax.helpers.defaulthandler; public class SAX2Count extends DefaultHandler { private static final String DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.saxparser"; private long elements; /** Elementos */ private long attributes; /** Atributos */ private long characters; /** Caracteres */ private long ignorablewhitespace; /** espacios en blanco */ /** Prints the output from the SAX callbacks. */ public static void print(string uri) { try { SAX2Count counter = new SAX2Count(); XMLReader parser = new org.apache.xerces.parsers.saxparser(); parser.setcontenthandler(counter); parser.seterrorhandler(counter); parser.setfeature( "http://xml.org/sax/features/validation", false); parser.setfeature( "http://xml.org/sax/features/namespaces", true); parser.setfeature( "http://apache.org/xml/features/validation/schema", true); 3

long before = System.currentTimeMillis(); parser.parse(uri); long after = System.currentTimeMillis(); counter.printresults(uri, after - before); catch (org.xml.sax.saxparseexception spe) { spe.printstacktrace(system.err); catch (org.xml.sax.saxexception se) { if (se.getexception()!= null) se.getexception().printstacktrace(system.err); else se.printstacktrace(system.err); catch (Exception e) { e.printstacktrace(system.err); // DocumentHandler methods public void startdocument() { elements = 0; attributes = 0; characters = 0; ignorablewhitespace = 0; public void startelement(string uri, String local, String raw, Attributes attrs) { elements++; if (attrs!= null) attributes += attrs.getlength(); public void characters(char ch[], int start, int length) { characters += length; public void ignorablewhitespace(char ch[], int start, int length) { ignorablewhitespace += length; // ErrorHandler methods public void warning(saxparseexception ex) { System.err.println("[Aviso] "+getloc(ex)+": "+ ex.getmessage()); public void error(saxparseexception ex) { System.err.println("[Error] "+getloc(ex)+": "+ex.getmessage()); public void fatalerror(saxparseexception ex) throws SAXException { System.err.println("[Error!] "+getloc(ex)+": "+ex.getmessage()); private String getloc(saxparseexception ex) { StringBuffer str = new StringBuffer(); String systemid = ex.getsystemid(); if (systemid!= null) { int index = systemid.lastindexof('/'); if (index!= -1) systemid = systemid.substring(index + 1); str.append(systemid); // str += ":" + ex.getlinenumber() + ":" + ex.getcolumnnumber(); str.append(':'); str.append(ex.getlinenumber()); str.append(':'); str.append(ex.getcolumnnumber()); 4

return str.tostring(); // Public methods public void printresults(string uri, long time) { // filename.xml: 631 ms (4 elems, 0 attrs, 78 spaces, 0 chars) System.out.println (uri+":"+time+"time ms (" +elements+" elems, "+attributes+" attrs, " +ignorablewhitespace+" spaces, "+characters+" chars)"); public static void main(string argv[]) { print(argv[0]); Una vez comprobado que la JVM funciona (ejecutar javac), se ha de configurar el CLASSPATH para que encuentre a las librerías de Xerces y JDOM (hacer que CLASSPATH=~/xerces/xerces.jar;/../jdom.jar que será diferente en cada entorno), entonces se puede copiar el programa anterior y probar que funciona correctamente. Hay una copia del programa y de Xerces en el web del laboratorio de AAD (http://www.ac.upc.es/docencia/fib/aad/lab) De forma alternativa, utilizando la forma de analizar xml del API DOM (que también implementa Xerces) el código sería así: package dom; import util.arguments; import java.io.outputstreamwriter; import java.io.printwriter; import java.io.unsupportedencodingexception; import org.apache.xerces.dom.textimpl; import org.w3c.dom.attr; import org.w3c.dom.document; import org.w3c.dom.namednodemap; import org.w3c.dom.node; import org.w3c.dom.nodelist; public class DOMCount { private static final String private static boolean setvalidation = false; //defaults private static boolean setnamespaces = true; private static boolean setschemasupport = true; private static boolean setdeferreddom = true; private long elements; /** Elements. */ private long attributes; /** Attributes. */ private long characters; /** Characters. */ private long ignorablewhitespace; /** Ignorable whitespace. */ /** Counts the resulting document tree. */ public static void count(string uri) { try { DOMParserWrapper parser = new dom.wrappers.domparser(); DOMCount counter = new DOMCount(); long before = System.currentTimeMillis(); parser.setfeature( "http://apache.org/xml/features/dom/defer-nodeexpansion", setdeferreddom ); parser.setfeature( "http://xml.org/sax/features/validation", setvalidation); parser.setfeature( "http://xml.org/sax/features/namespaces", setnamespaces); parser.setfeature( "http://apache.org/xml/features/validation/schema",setschemasupport); Document document = parser.parse(uri); 5

counter.traverse(document); long after = System.currentTimeMillis(); counter.printresults(uri, after - before); catch (org.xml.sax.saxparseexception spe) { catch (org.xml.sax.saxnotrecognizedexception ex ){ catch (org.xml.sax.saxnotsupportedexception ex ){ catch (org.xml.sax.saxexception se) { if (se.getexception()!= null) se.getexception().printstacktrace(system.err); else se.printstacktrace(system.err); catch (Exception e) { e.printstacktrace(system.err); /** Traverses the specified node, recursively. */ public void traverse(node node) { if (node == null) return; // is there anything to do? switch (node.getnodetype()) { case Node.DOCUMENT_NODE: // print document elements = 0; attributes = 0; characters = 0; ignorablewhitespace = 0; traverse(((document)node).getdocumentelement()); break; case Node.ELEMENT_NODE: {// print element with attributes elements++; NamedNodeMap attrs = node.getattributes(); if (attrs!= null) attributes += attrs.getlength(); NodeList children = node.getchildnodes(); if (children!= null) { int len = children.getlength(); for (int i = 0; i < len; i++) traverse(children.item(i)); break; case Node.ENTITY_REFERENCE_NODE: { NodeList children = node.getchildnodes(); if (children!= null) { int len = children.getlength(); for (int i = 0; i < len; i++) traverse(children.item(i)); break; case Node.CDATA_SECTION_NODE: // print text characters += node.getnodevalue().length(); break; case Node.TEXT_NODE: if (node instanceof TextImpl) { if (((TextImpl)node).isIgnorableWhitespace()) ignorablewhitespace += node.getnodevalue().length(); else characters += node.getnodevalue().length(); else characters += node.getnodevalue().length(); break; public void printresults(string uri, long time) { // filename.xml: 631 ms (4 elems, 0 attrs, 78 spaces, 0 chars) System.out.println (uri+":"+time+"time ms (" +elements+" elems, "+attributes+" attrs, " +ignorablewhitespace+" spaces, "+characters+" chars)"); 6

public static void main(string argv[]) { count(argv[0] ); //count uri Los API anteriores están disponibles para multitud de lenguajes de programación, pero a cambio de la portabilidad del API, el uso es engorroso desde Java. Se ha diseñado una librería específica para Java (JDOM), pero que a cambio utiliza las capacidades particulares del lenguaje Java, que simplifica notablemente la programación. Puede encontrarse más información en http://www.jdom.org El ejemplo anterior escrito usando el API JDOM sería: import org.jdom.*; import org.jdom.input.saxbuilder; import org.jdom.input.dombuilder; import org.jdom.output.*; import java.util.*; public class Count { public static void main(string[] args) { if (args.length == 0) { System.out.println("Usage: java Count URL"); SAXBuilder saxbuilder = new SAXBuilder(); DOMBuilder dombuilder = new DOMBuilder(); System.out.println("File\tElements\tAttributes\tComments\tProcessing Instructions\tCharacters"); // start parsing... try { Document jdomdocument = saxbuilder.build(args[0]); DOMOutputter domoutputter = new DOMOutputter(); /* Test getting DOM Document from JDOM Document org.w3c.dom.document domdocument = domoutputter.output(doc); */ // Test getting DOM Element from JDOM Element org.w3c.dom.element domelement = domoutputter.output(jdomdocument.getrootelement()); // Test getting JDOM Element from DOM Element org.jdom.element jdomelement = dombuilder.build(domelement); count(jdomelement); catch (JDOMException e) { // indica doc mal formado u otro error System.out.println("Documento XML mal formado o incorrecto."); System.out.println(e.getMessage()); private static int numcharacters = 0; private static int numcomments = 0; private static int numelements = 0; private static int numattributes = 0; private static int numprocessinginstructions = 0; public static String count(document doc) { numcharacters = 0; numcomments = 0; numelements = 0; numattributes = 0; numprocessinginstructions = 0; List children = doc.getmixedcontent(); Iterator iterator = children.iterator(); while (iterator.hasnext()) { 7

Object o = iterator.next(); if (o instanceof Element) { numelements++; count((element) o); else if (o instanceof Comment) numcomments++; else if (o instanceof ProcessingInstruction) numprocessinginstructions++; String result = numelements + "\t" + numattributes + "\t" + numcomments + "\t" + numprocessinginstructions + "\t" + numcharacters; return result; public static void count(element element) { List attributes = element.getattributes(); numattributes += attributes.size(); List children = element.getmixedcontent(); Iterator iterator = children.iterator(); while (iterator.hasnext()) { Object o = iterator.next(); if (o instanceof Element) { numelements++; count((element) o); else if (o instanceof Comment) numcomments++; else if (o instanceof ProcessingInstruction) numprocessinginstructions++; else if (o instanceof String) { String s = (String) o; numcharacters += s.length(); String result = numelements + "\t" + numattributes + "\t" + numcomments + "\t" + numprocessinginstructions + "\t" + numcharacters; System.out.println(result); Probar los ejemplos anteriores. Para probar JDOM, se ha de descargar la librería jdom.jar (del web de lab) y colocarla en el CLASSPATH. En el web de laboratorio podréis encontrar páginas de ayuda sobre JDOM. Tienda de muebles en XML Ahora se trata de diseñar los intercambios entre compradores, proveedores y la tienda en forma xml. Para ello a partir de un documento xml de partida (en el web de lab), hay que diseñar el DTD que le corresponda. Para poder probar que el DTD es correcto, se podría hacer un analizador DOM que validara el documento y avisara de los posibles errores. En lugar de programarlo, se puede usar el analizador XML (que incluye el API DOM) incluido a partir de la versión 5.0 de MS Internet Explorer. Se puede crear el fichero shop.dtd en el mismo directorio donde esté shop.xml, y pedirle a MSIE que abra el fichero local shop.xml. El MSIE verificará la sintaxis del DTD, os indicará los errores, y si el DTD es correcto, verificará si el documento xml cumple con la especificación. Así se puede comprobar cómodamente que el DTD está bien escrito y describe bien a shop.xml. Shop.xml tal como lo presenta MSIE tras validar shop.dtd y verificar que shop.xml está bien formado. 8

<?xml version="1.0" encoding="utf-8" standalone="no"?> <!DOCTYPE shop (View Source for full doctype...)> - <list> - <op name="supply"> <item precio="123456" unidades="60">mesa comedor haya</item> <item precio="13456" unidades="100">mesa cocina nogal</item> <item precio="13457" unidades="200">silla cocina nogal</item> </op> <res name="supply" /> - <op name="order" u="juan" pass="nauj"> <item unidades="1">mesa comedor haya</item> <item unidades="4">silla cocina nogal</item> </op> - <res name="order"> - <order> <id>345</id> <item unidades="1" precio="123456">mesa comedor haya</item> <item unidades="4" precio="13457">silla cocina nogal</item> <total>177284</total> </order> </res> <op name="list" u="juan" pass="nauj" /> - <res> - <order> <id>345</id> <item unidades="1" precio="123456">mesa comedor haya</item> <item unidades="4" precio="13457">silla cocina nogal</item> <total>177284</total> </order> - <order> <item unidades="0" precio="123456">mesa comedor haya</item> </order> <total>1234567</total> </res> </list> En segundo lugar, modificar el ejemplo de contador con JDOM para leer un documento xml como shop.xml y que escriba en la salida en forma textual, la lista de pedidos con los datos que aparecen en el documento xml. Información adicional de JDOM puede encontrarse en el web de lab y en el web de jdom: http://www.jdom.org. 9