Construir un documento XML para el siguiente pedido que ha recibido por correo electr�nico una empresa que se dedica a la venta de herramientas para jardiner�a:
"Hola, necesito una cortadora de cesped para mi jard�n de esas que anuncian en oferta, me gustar�a que fuera uno de esos modelos el�ctricos, pues las de gasolina contaminan mucho. Me llamo Roberto Movilla, la cortadora la tendr�n que enviar a Albacete, la direcci�n es Plaza de la Duquesa 12, la recoger� mi esposa que se llama Alicia Abad. Ahora que lo pienso tambi�n necesitar� 3 podadoras para los setos. Les paso mi direcci�n de aqu� para lo referente al pago, es General Ricardos 56, aqu� en Madrid. Es urgente, por favor, el c�sped 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 c�digo postal de la direcci�n de Albacete es 05020 y el de la de Madrid 28055; tambi�n ha consultado el cat�logo de productos y ha averiguado que la cortadora vale 148.95 euros y su c�digo de producto es 872-AA, aunque no sabe si es o no el�ctrica; una podadora vale 7.98 y su c�digo es 926-FH.
�Soluci�n
<?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 c�sped 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 el�ctrica</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.
�Soluci�n
<!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>Introducci�n</Tema> <Seccion apartados="7">Qu� es</Seccion> <Seccion apartados="3">C�mo 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">Preparaci�n</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">Introducci�n</Seccion> <Seccion apartados="4" dificil="true">DOM&JDOM</Seccion> </Capitulo> </Contenido> <Copyright>&OReillyCopyright;</Copyright> </Libro>
�Soluci�n
<?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 caracter�sticas: las empresas aparecen ordenadas por el precio de cotizaci�n, 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 explicaci�n debajo de la tabla. El t�tulo del documento refleja el d�a y hora de la informaci�n.
<?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>
�Soluci�n
<?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>S�mbolo</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 > 75"> <font color="blue"><xsl:value-of select="Bolsa:Precio"/></font> </xsl:when> <xsl:when test="Bolsa:Precio < 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 t�tulos de los cap�tulos y un peque�o resumen para cada uno de ellos con el n�mero de secciones, de apartados totales y de apartados dif�ciles.
�Soluci�n
import java.io.IOException; import java.io.FileWriter; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.helpers.XMLReaderFactory; public class EjercicioSAX { public static void main(String[] args) { if (args.length != 1) { System.out.println("Debe haber un par�metro (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 an�lisis. Todo bien\n"); } catch (IOException e) { System.out.println(e); } catch (SAXException e) { System.out.println(e); } } } } class ManejadorCaps implements ContentHandler { private Locator loc; private FileWriter f; private boolean extraer; private int numSecciones; private int numApartados; private 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 + " dif�ciles)\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 t�tulos de los cap�tulos y un peque�o resumen para cada uno de ellos con el n�mero de secciones, de apartados totales y de apartados dif�ciles.
�Soluci�n
import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.w3c.dom.NamedNodeMap; import java.io.IOException; import org.xml.sax.SAXException; import org.apache.xerces.parsers.DOMParser; import java.io.FileWriter; public class EjercicioDOM { static FileWriter f; static int numSecciones; static int numApartados; static 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(Dif�ciles: " + 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 par�metro (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 informaci�n. 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>
�Soluci�n
import org.w3c.dom.*; import javax.xml.parsers.*; import org.apache.xerces.dom.DocumentImpl; import org.apache.xml.serialize.*; import 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, "hw1")); notas[numStud][1] = Integer.parseInt(extraerValor(elemStud, "hw2")); notas[numStud][2] = Integer.parseInt(extraerValor(elemStud, "project")); notas[numStud][3] = Integer.parseInt(extraerValor(elemStud, "final")); } 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); 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); } } }