=== XML === Introducción ============ Los lenguajes de marcas como HTML tienen una orientación muy clara: describir páginas web. En un contexto distinto, muy a menudo ocurre que es muy difícil intercambiar datos entre programas. XML es un conjunto de tecnologías orientadas a crear nuestros propios lenguajes de marcas. A estos lenguajes de marcas "propios" se les denomina "vocabularios". Un ejemplo sencillo =================== .. code-block:: xml AcerSA 5664332 Mer SL 5111444 Lo fundamental es que podemos crear nuestros propios "vocabularios" XML. Construcción de XML =================== Para crear XML es importante recordar una serie de reglas: * XML es "case-sensitive", es decir que no es lo mismo mayúsculas que minúsculas y que por tanto no es lo mismo ````, que ```` que ````. * Obligatorio: solo un elemento raíz. * En general, la costumbre es poner todo en minúsculas. * Solo se puede poner una etiqueta que empiece por letra o _. Es decir, esta etiqueta no funcionará en los programas ``<12Cliente>``. * Aparte de eso, una etiqueta sí puede contener números, por lo que esta etiqueta sí es válida ````. * Aunque no es obligatorio a menudo se suele poner en la primera línea un **prólogo** que indica la versión de XML que estamos usando y la codificación con la que nuestro editor almacena los archivos. Validez ======= Un documento XML puede "estar bien formado" o "ser válido". Se dice que un documento "está bien formado" cuando respeta las reglas XML básicas. Si alguien ha definido las reglas XML para un vocabulario, podremos además decir si el documento es válido o no, lo cual es mejor que simplemente estar bien formado. Por ejemplo, los siguientes archivos ni siquiera están bien formados. .. code-block:: xml AcerSA 5666333 En este caso la etiqueta ```` no está cerrada. .. code-block:: xml AcerSA 5666333 En este caso, se ha puesto ```` cerrado con ```` (mayúsculas). .. code-block:: none AcerSA 5666333 Se ha utilizado la admiración, que no es válida (de hecho, el coloreador de sintaxis automático descubre que no es XML y el fichero se muestra de manera literal) Atención a este ejemplo: .. code-block:: xml AcerSA 5666333 ACME 455321 En este caso, el problema es que hay más de un elemento raíz. En general, podemos asumir que un documento puede estar en uno de estos estados que de peor a mejor podríamos indicar así: 1. Mal formado (lo peor) 2. Bien formado. 3. Válido: está bien formado y además nos han dado las reglas para determinar si algo está bien o mal y el documento XML cumple dichas reglas. Este es el mejor caso. Para determinar si un documento es válido o no, se puede usar el validador del W3C situado en http://validator.w3c.org Gramáticas ========== Pensemos en el siguiente problema, un programador crea aplicaciones con documentos que se almacenan así: .. code-block:: xml AcerSA 455321 ACME 455321 Sin embargo, otro programador de la misma empresa lo hace así: .. code-block:: xml 455321 AcerSA 455321 ACME Está claro, que ninguno de los dos puede leer los archivos del otro, sería crítico ponerse de acuerdo en lo que se puede hacer, lo que puede aparecer y en qué orden debe hacerlo. Esto se hará mediante las DTD. DTD significa Declaración de Tipo de Documento, y es un mecanismo para expresar las reglas sobre lo que se va a permitir y lo que no en archivos XML. Por ejemplo, supongamos el mismo ejemplo ejemplo anterior en el que queremos formalizar lo que puede aparecer en un fichero de clientes. Se debe tener en cuenta que en un DTD se pueden indicar reglas para lo siguiente: * Se puede indicar si un elemento aparece o no de forma opcional (usando ``?``) * Se puede indicar si un elemento debe aparecer de forma obligatoria. * Se puede indicar si algo aparecer una o muchas veces (usando ``+``). * Se puede indicar si algo aparece cero o muchas veces (usando ``*``). * Se puede indicar que un elemento ya no lleva nada dentro usando ````. Dentro de ```` deseamos permitir uno o más elementos ````. Dentro de ```` todos deberán tener ```` y ```` y en ese orden. Dentro de ```` puede aparecer o no un elemento ```` para indicar que ese cliente exige un máximo de plazos. Como no todo el mundo usa plazos el ```` es optativo. Por ejemplo, este XML sí es válido: .. code-block:: xml 5676443 Mercasa Este también lo es: .. code-block:: xml 5676443 Mercasa 30 Este también: .. code-block:: xml 5676443 Mercasa 30 5121554 Acer SL Sin embargo, estos no lo son: .. code-block:: xml Este archivo no tenía clientes (y era obligatorio al menos uno) .. code-block:: xml 5676443 30 Este archivo no tiene nombre de cliente. .. code-block:: xml Mercasa 5676443 5121554 Acer SL En este archivo no se respeta el orden cif, nombre. Sintaxis DTD ---------------------------------------------- Una DTD es como un CSS, puede ir en el mismo archivo XML o puede ir en uno separado. Para poder subirlos al validador, meteremos la DTD junto con el XML. La primera línea de todo XML debe ser esta: .. code-block:: xml Al final del XML pondremos los datos propiamente dichos .. code-block:: xml Mercasa 5676443 5121554 Acer SL La DTD tiene esta estructura .. code-block:: dtd ] > Esto significa lo siguiente: * Se establece el tipo de documento ``listaclientes`` que consta de una serie de elementos (dentro del corchete) * Un elemento ``listaclientes`` consta de uno o más clientes. El signo ``+`` significa "uno o más". * Un cliente tiene un nombre y un cif. También puede tener un elemento ``diasentrega`` que puede o no aparecer (el signo ``?`` significa "0 o 1 veces"). * Un ``nombre`` no tiene más elementos dentro, solo caracteres (``#PCDATA``) * Un ``CIF`` solo consta de caracteres. * Un elemento ``diasentrega`` consta solo de caracteres. La solución completa sería así: .. code-block:: xml ]> Mercasa 5676443 Acer SL 5121554 Combinaciones de cuantificadores y listas de opciones --------------------------------------------------------- Hay un problema cuando algunas reglas involucran estructuras complejas. Por ejemplo, sin pensamos en una descripción como : "Dentro de listaventas, primero habrá una secuencia de elementos ventapc y despues ventamonitor" entonces este fichero *sí debería aceptarse* .. code-block:: xml 100 300 400 200 400 500 Y este fichero no debería aceptarse: .. code-block: xml 100 200 300 400 400 Pues bien, la regla sería esta: en ella se pone **una secuencia SEGUIDA DE otra secuencia** .. code-block:: dtd Supongamos esta otra descripción: "Dentro de listaventas, puede haber cualquier orden de elementos ventapc y ventamonitor, se pueden repetir las veces que hagan falta en cualquier orden e incluso intercalados". Es decir, esto se acepta .. code-block:: html 100 300 400 200 400 500 Pero esto también .. code-block:: html 100 200 300 400 400 Pues bien, la DTD sería la siguiente: .. code-block:: dtd Compárese con el anterior .. code-block:: El anterior obliga a llevar un orden, pero en el ejercicio se aceptaba el "desorden". Pregunta: **¿Por qué esto está mal?** .. code-block:: dtd Está mal porque obliga a "escribir secuencias de parejas ventapc, ventamonitor como en el fichero siguiente". .. code-block:: xml 100 400 100 400 100 400 Y esto NO ERA LO QUE SE PEDÍA. Ahora se exige un fichero en el que pase una de estas dos cosas de acuerdo a esta descripción: "los elementos pueden aparecer en cualquier orden, pero en en fichero solo pueden aparecer ventas o compras". O sea, que esto sí es válido .. code-block:: 800 800 Y esto otro también es válido: .. code-block:: 100 3000 **Pero esto no está permitido** .. code-block:: 100 3000 Pues bien, la regla es esta: .. code-block:: dtd Ejemplo de DTD (productos) --------------------------------- Se pide un conjunto de reglas en forma de DTD para definir qué se permitirá en los archivos XML de datos de una empresa de fabricación: * La raíz es * Dentro de productos puede haber o que pueden repetirse e ir en cualquier orden (RRTT, T, TR, TTRR) * Todo tiene siempre un y puede o no tener una . * Todo tiene siempre un , debe llevar siempre una y puede o no tener un Elaborar la DTD que formaliza estas reglas. Analicemos algunas posibilidades para la raíz,por ejemplo esta: .. code-block:: dtd Esto está MAL. Exige que dentro de productos haya exactamente un ratón y despues un teclado, y solo uno de cada. Veamos otra: .. code-block:: dtd También está MAL. Exige que haya raton y despues teclado. Es cierto que permite repetir elementos, pero esa repetición es de la pareja, es decir obligamos a que los ficheros sean así: .. code-block:: xml Echemos un vistazo a otra posible regla para la raíz: .. code-block:: dtd Esto también está mal. Permite que no haya nada dentro de productos, pero ni siquiera nos hablan de eso. Veamos otra: .. code-block:: dtd Esto también está mal porque nos ofrece que dentro de "productos" haya un ratón o un teclado. Es cierto que ofrece algo de flexibilidad, pero aún no es lo que queremos. Otra regla raíz equivocada sería esta: .. code-block:: dtd Esto también está mal. Permite que dentro de productos haya una sola de estas cosas * O una secuencia de "raton" * O una secuencia de "teclado" ¡Pero no permite secuencias con mezcla! Veamos, ahora sí, una solución correcta .. code-block:: dtd El siguiente fichero debe validarse correctamente: .. code-block:: xml Y el siguiente también .. code-block:: xml T1 Teclado inalamb. Y este también (a pesar del flagrante error en el peso) .. code-block:: xml R1 T1 Teclado inalamb. |@¬|@~||@~ Ejercicio I (DTD) =================================================== Unos programadores necesitan un formato de fichero para que sus distintos programas intercambien información sobre ventas. El acuerdo al que han llegado es que su XML debería tener esta estructura: * El elemento raíz será ```` * Toda ```` tiene una o más ventas. * Toda ```` tiene los siguientes datos: * Importe. * Comprador. * Vendedor. * Fecha (optativa). * Un codigo de factura. .. code-block:: xml ]> 1500 Wile E.Coyote ACME E17 750 Elmer Fudd ACME 27-2-2015 E18 Ejercicio II (DTD) =========================================== Crear un XML de ejemplo y la DTD asociada para unos programadores que programan una aplicación de pedidos donde hay una lista de pedidos con 0 o más pedidos. Cada pedido tiene un número de serie, una cantidad y un peso que puede ser opcional. Solución ---------------------------------------------- Este ejemplo es un documento XML válido. .. code-block:: xml ]> Este documento **no es válido** .. code-block:: xml ]> 23332244 Este documento **sí es válido**. Las DTD solo se ocupan de determinar qué elementos hay y en qué orden, pero no se ocupan de lo que hay dentro de los elementos. .. code-block:: xml ]> 23332244 ññlñ Ejercicio III ================================================================================ Se desea crear una gramática para ficheros de datos en los que se ha decidido contemplar lo siguiente: * El fichero debe llevar una raíz ```` * Dentro debe haber uno o más elementos ```` * Dentro de productos debe haber alguno de estos ```` , ```` , ```` o ```` * Todo ratón, teclado o monitor tiene siempre un código. * Todo ratón, teclado o monitor puede llevar un nombre. * Todo ratón, teclado o monitor puede llevar una descripción. .. code-block:: xml 27A 28D Teclado en Español Solución al ejercicio III -------------------------------------------------------------------------------- .. code-block:: dtd Ejercicio IV ================================================================================ Unos programadores necesitan un formato de fichero para que sus distintos programas intercambien información sobre ventas. El acuerdo al que han llegado es que su XML debería tener esta estructura: * El elemento raíz será * Toda tiene una o más . * Toda tiene los siguientes datos: * Importe. * Comprador. * Vendedor. * Fecha (optativa). * Un codigo de factura. Solución al ejercicio IV -------------------------------------------------------------------------------- Por ahora no se dará la solución de este ejercicio. Inténtalo y si no puedes pide ayuda al profesor o escríbele un email para averiguar como resolverlo. Ejercicio V DTD ================================================================================ En un departamento se ha decidido la siguiente estructura para ficheros de datos que se tengan que mover de unos software a otros. * La raíz debe ser el elemento ```` * Dentro de ```` debe haber uno o más elementos ```` * Una ``venta`` puede llevar dentro uno de dos: ```` o ```` * Un elemento ```` consta de : un elemento ```` que es optativo y un elemento ```` que es obligatorio. * Un elemento ```` lleva dentro dos cosas: un elemento ```` que es obligatorio y un elemento ```` que también es obligatorio. Solución al ejercicio V -------------------------------------------------------------------------------- Puedes usar este ejemplo para hacer la validación: .. code-block:: xml 22-10-2021 21000 1800 euros 21000 <<<<<<< HEAD Una posible solución sería: .. code-block:: dtd Ejercicio VI DTD ================================================================================ Un mayorista de productos de librería desea tener un formato de almacenamiento de datos para reflejar la información de su inventario. * El elemento raíz debe ser ```` * Dentro de inventario pueden ir elementos ````, ```` o ```` repetidos y en cualquier orden. * Todo ```` puede tener un elemento ```` * Todo cuaderno debe llevar dos elementos: ```` y ```` * Todo boligrafo lleva un ```` y puede o no llevar un elemento ```` El siguiente fichero debería ser validado por la DTD: .. code-block:: xml H2 80 2 rayas 0.80 100 Cuadriculado 0.80 Rojo .. code-block:: dtd Ejercicio (con atributos) =========================== Unos programadores necesitan estructurar la información que intercambiarán los ficheros de sus aplicaciones para lo cual han determinado los requisitos siguientes. * Los ficheros deben tener un elemento ```` * Dentro de la lista debe haber una o más facturas. * Las facturas tienen un atributo ``fecha`` que es optativo. * Toda factura tiene un ``emisor``, que es un elemento obligatorio y que debe tener un atributo ``cif`` que es obligatorio. Dentro de ``emisor`` debe haber un elemento ``nombre``, que es obligatorio y puede o no haber un elemento ``volumenventas``. * Toda factura debe tener un elemento ``pagador``, el cual tiene exactamente la misma estructura que ``emisor``. * Toda factura tiene un elemento ``importe``. Solución ejercicio con atributos ------------------------------------------------------ La siguiente DTD refleja los requisitos indicados en el enunciado. .. code-block:: dtd Y el XML siguiente refleja un posible documento. Puede comprobarse que es válido con respecto a la DTD. .. code-block:: xml ACME ACME Inc 2000 2500 Ejercicio ========= Un instituto necesita registrar los cursos y alumnos que estudian en él y necesita una DTD para comprobar los documentos XML de los programas que utiliza: * Tiene que haber un elemento raíz ``listacursos``. Tiene que haber uno o más cursos. * Un curso tiene uno o más alumnos * Todo alumno tiene un DNI, un nombre y un apellido, puede que tenga segundo apellido o no. * Un alumno escoge una lista de asignaturas donde habrá una o más asignaturas. Toda asignatura tiene un nombre, un atributo código y un profesor. * Un profesor tiene un NRP (Número de Registro Personal), un nombre y un apellido (también puede tener o no un segundo apellido). Solución completa ---------------------------------------------- .. code-block:: xml Un ejemplo de fichero válido: .. code-block:: xml 44e Juan Sanchez Leng marcas 8 Oscar Gomez Otras características de XML ============================ Atributos ---------------------------------------------- Un atributo XML funciona exactamente igual que un atributo HTML, en concreto un atributo es un trozo de información que acompaña a la etiqueta, en lugar de ir dentro del elemento. .. code-block:: xml ... En este caso, la etiqueta ``pedido`` tiene un atributo ``codigo``. ¿Cuando debemos usar atributos y cuando debemos usar elementos? Resulta que el ejemplo anterior también se podría haber permitido hacerlo así: .. code-block:: xml 20C ... Hay muchas discusiones sobre qué meter dentro de elemento o atributo. Sin embargo, los expertos coinciden en señalar que en caso de duda es mejor el segundo. La definición de atributos se hace por medio de una directiva llamada ``ATTLIST``. En concreto si quisieramos permitir un atributo ``código`` en el elemento ``pedido`` se haría algo así. .. code-block:: xml ]> Pedido de cosas En concreto este código pone que el elemento ``pedido`` tiene un atributo ``código`` con datos carácter dentro y que es obligatorio que esté presente (un atributo optativo en vez de ``#REQUIRED`` usará ``#IMPLIED``) Si probamos esto, también validará porque el atributo es *optativo* .. code-block:: xml ]> Pedido de cosas Elementos vacíos ---------------------------------------------- En ocasiones, un elemento en especial puede interesarnos que vaya vacío porque simplemente no contiene mucha información de relevancia. Por ejemplo en HTML podemos encontrarnos esto: .. code-block:: html Texto texto...
Los elementos vacíos suelen utilizar para indicar pequeñas informaciones que no deseamos meter en atributos y que de todas formas tampoco son de demasiada relevancia. Un elemento vacío se indica poniendo ``EMPTY`` en lugar de ``#PCDATA`` Por supuesto, estas dos formas de usar un atributo son válidas: .. code-block:: xml ... .. code-block:: xml ... La definición completa sería así: .. code-block:: xml ]> Pedido de cosas Alternativas ---------------------------------------------- Hasta ahora hemos indicado elementos donde un elemento puede aparecer o puede no aparecer, pero ¿qué ocurre si deseamos obligar a que aparezca una posibilidad entre varias? Por ejemplo, supongamos que en un nuestro ejemplo de pedidos deseamos indicar si el pedido se entregó en almacén o a domicilio. A la fuerza todo pedido se entrega de alguna manera, sin embargo queremos exigir que en los XML aparezca una de esas dos alternativas. Los elementos alternativos se indican con la barra vertical ``almacen|domicilio`` Una tentación sería hacer esto (que está **mal**): .. code-block:: xml ]> Está mal porque se permite esto: .. code-block:: xml Ordenadores Entregado el 20-2-2011 Entregado el 20-2011 La forma **correcta** es esta: .. code-block:: xml ]> Ordenadores Ejercicio =========================================== Un mayorista informático necesita especificar las reglas de los elementos permitidos en las aplicaciones que utiliza en sus empresas, para ello ha indicado los siguientes requisitos: * Una entrega consta de uno o más lotes. * Un lote tiene uno o más palés * Todo palé tiene una serie de elementos: número de cajas, contenido y peso y forma de manipulación. * El contenido consta de una serie de elementos: nombre del componente, procedencia (puede aparecer 0, 1 o más países), número de serie del componente, peso del componente individual y unidad de peso que puede aparecer o no. Solución ---------------------------------------------- Observa como en la siguiente DTD se pone ``procedencia?`` y dentro de ella ``pais+``. Esto nos permite que si aparece la procedencia se debe especificar uno o más países. Sin embargo si no queremos que aparezca ningun pais, el XML **no necesita contener un elemento vacío**. .. code-block:: dtd .. code-block:: xml 3 Fuentes 3A 2kg 50 100kg Manual 2 CPUs China Corea del Sur 5B 100g 1000 100kg Manual Ejercicio: mayorista de libros ====================================== Se desea crear un formato de intercambio de datos para una empresa mayorista de libros con el fin de que sus distintos programas puedan manejar la información interna. El formato de archivo debe tener la siguiente estructura: * El elemento raíz es "operaciones". * Dentro de "operaciones" hay uno o más elementos "operacion". * Una "operacion" puede ser "venta", "compra", o cualquier combinación y secuencia de ellas, pero debe haber al menos una. * Una venta tiene dentro un elemento "titulosvendidos". Dentro de "titulosvendidos" se almacenan estos datos: * Uno o más elementos "título". * La cantidad total de libros vendidos. * Puede haber un elemento "entregado" que indique si la entrega se ha realizado. * Debe haber un elemento importe con un atributo obligatorio llamado "moneda". * Una compra tiene dentro un elemento "tituloscomprados". Dentro de él hay esto: * Uno o más elementos "titulo" * Un "proveedor". * Una fecha de compra, que debe desglosarse en elementos día, mes y año El objetivo final debe ser validar un fichero como este: .. code-block:: xml Don Quijote Rimas y leyendas 2000 4400 Rinconete y Cortadillo Sainetes 1000 290 De la Tierra a la Luna Barbarroja Editorial EDSA 10 6 2018 Cinco semanas en globo Sainetes 700 1490 De la Tierra a la Luna Barbarroja Editorial Recopila 2 12 2017 Solución al mayorista de libros ------------------------------------------------------ La siguiente DTD valida el fichero arriba mostrado: .. code-block:: dtd Ejercicio: fabricante de tractores =========================================== Un fabricante de tractores desea unificar el formato XML de sus proveedores y para ello ha indicado que necesita que los archivos XML cumplan las siguientes restricciones: * Un pedido consta de uno o más tractores. * Un tractor consta de uno o más componentes. * Un componente tiene los siguientes elementos: nombre del fabricante (atributo obligatorio), fecha de entrega (si es posible, aunque puede que no aparezca, si aparece el dia es optativo, pero el mes y el año son obligatorios). También se necesita saber del componente si es frágil o no. También debe aparecer un elemento peso del componente y dicho elemento peso tiene un atributo unidad del peso (kilos o gramos), un elemento número de serie y puede que aparezca o no un elemento kmmaximos indicando que el componente debe sustituirse tras un cierto número de kilómetros. Un posible fichero de ejemplo que podría validar sería este: .. code-block:: xml 2018 2018 12 00A 1212019 1450 00D 25000 770 43Z Solución: DTD fabricante tractores -------------------------------------- .. code-block:: dtd Ejercicio: repeticiones de opciones =================================== Se necesita un formato de archivo para intercambiar productos entre almacenes de productos de librería y se desea una DTD que incluya estas restricciones: * Debe haber un elemento raíz pedido que puede constar de libros, cuadernos y/o lápices. Los tres elementos pueden aparecer repetidos y en cualquier orden. Tambien pueden aparecer por ejemplo 4 libros, 2 lapices y luego 4 lapices de nuevo. * Todo libro tiene un atributo obligatorio titulo. * Los elementos cuaderno tiene un atributo optativo num_hojas. * Todo elemento lápiz debe tener dentro un elemento obligatorio número. La solución a la DTD: .. code-block:: dtd .. code-block:: xml 2H 2B 1HB Ejercicio: multinacional =========================== Una multinacional que opera en bolsa necesita un formato de intercambio de datos para que sus programas intercambien información sobre los mercados de acciones. En general todo archivo constará de un listado de cosas como se detalla a continuación * En el listado aparecen siempre uno o varios futuros, despues una o varias divisas, despues uno o varios bonos y una o varias letras. * Todos ellos tienen un atributo precio que es **obligatorio** * Todos ellos tienen un elemento vacío que indica de donde es el producto anterior: "Madrid", "Nueva York", "Frankfurt" o "Tokio". * Las divisas y los bonos tienen un atributo optativo que se usa para indicar si el producto ha sido estable en el pasado o no. * Un futuro es un valor esperado que tendrá un cierto producto en el futuro. Se debe incluir este producto en forma de elemento. También puede aparecer un elemento mercado que indique el país de procedencia del producto. * Todo bono tiene un elemento país_de_procedencia para saber a qué estado pertenece. Debe tener tres elementos extra llamados "valor_deseado", "valor_mínimo" y "valor_máximo" para saber los posibles precios. * Las divisas tienen siempre un nombre pueden incluir uno o más tipos de cambio para otras monedas. * Las letras tienen siempre un tipo de interés pagadero por un país emisor. El país emisor también debe existir y debe ser siempre de uno de los países cuyas capitales aparecen arriba (es decir "España", "EEUU", "Alemania" y "Japón" .. code-block:: xml ]> Cafe América Latina Libra esterlina 2.7:1 euros 1:0.87 dólares Islandia 9980 9950 10020 4.54% Otros ejercicios DTD ========================== Inventario de piezas ------------------------ Se desea almacenar nombres de piezas y para ello se ha llegado a este acuerdo: 1.- El elemento raíz se va a llamar "listapiezas". 2.- Dentro de "listapiezas" va a haber uno o muchos elementos "pieza" 3.- Dentro de "pieza" hay tres elementos: 3.1 Un elemento llamado "peso" que contiene datos 3.2 Un elemento llamado "nombre" que contiene datos 3.3 Un elemento llamado fabricante que contiene datos. 3.3.1 El fabricante lleva un atributo llamado pais que indica el pais Ejemplo de fichero válido 20 Pistón Asia Electronics 15 Cilindro Toyota Motors Ejemplo de fichero que debe dar errores .. code-block:: xml 20 Pistón Asia Electronics 15 Toyota Motors Una posible solución sería esta:: .. code-block:: dtd Almacén de repuestos --------------------------- Una empresa de repuestos desea almacenar en XML la información de su inventario: 1. El elemento raíz debe ser "repuestos" 2. Dentro de "repuestos" debe haber uno o más "repuesto". 3. Dentro de "repuesto" debe haber una de estas dos cosas: "tornillo" o "tuerca" 3.1 Tornillo: lleva siempre un atributo "peso". Lleva dentro un elemento llamado "descripcion" 3.2 Tuerca: puede llevar un atributo "peso". Lleva dentro siempre un elemento llamado "material" Ejemplo de fichero válido .. code-block:: xml Tornillo para ensamblajes metálicos Acero Aleación Y una posible solución: .. code-block:: dtd Suministros médicos (DTD) ----------------------------- En un centro médico se desea almacenar la información sobre el inventario usando XML. Se ha llegado a un acuerdo para almacenar la información en este formato 1. El elemento raíz se llama "suministrosmedicos". Dentro de él hay lo siguiente: 1.1 Primero hay uno o muchos elementos "antibiotico". Todo antibiotico lleva dentro un elemento "nombre". Puede llevar o no un elemento llamado "nombrecomercial". 1.2 Despues hay uno o muchos elementos "analgesico". El analgesico puede llevar dentro o no un elemento "fechadecaducidad" y despues siempre un elemento nombre. El analgesico siempre lleva un atributo llamado "pvp". 1.3 Despues puede haber 0 o muchos elementos "antitusivo". Todo antitusivo lleva dentro dos elementos QUE PUEDEN IR EN CUALQUIER ORDEN: elemento "tiporeceta" y el elemento "presentacion". La presentacion siempre lleva un atributo "dosisrecomendada" A continuación se da un ejemplo de fichero: .. code-block:: xml Penicilina Penicilina Zitromax Amoxicilina Paracetamol 15-02-2026 Apiretal Innecesaria Jarabe Jarabe Atencion primaria Atencion primaria Pastillas Y una posible solución: .. code-block:: dtd Ejercicio =========================================== La Seguridad Social necesita un formato de intercambio unificado para distribuir la información personal de los afiliados. * Todo archivo XML contiene un listado de uno o mas afiliados * Todo afiliado tiene los siguientes elementos: * DNI o NIE * Nombre * Apellidos * Situación laboral: que tiene que ser una y solo una de entre estas posibilidades: "en_paro", "en_activo", "jubilado", "edad_no_laboral" * Fecha de nacimiento: que se desglosa en los elementos obligatorios día, mes y anio. * Listado de bajas: que indica las situaciones de baja laboral del empleado. Dicho listado consta de una repetición de 0 o más bajas: * Una baja consta de tres elementos: causa (obligatoria), fecha de inicio (obligatorio) y fecha de final (optativa), * Listado de prestaciones cobradas: consta de 0 o más elementos prestación, donde se indicará la cantidad percibida (obligatorio), la fecha de inicio (obligatorio) y la fecha de final (obligatorio) Inventario de piezas (variante) ----------------------------------- Se desea almacenar nombres de piezas y para ello se ha llegado a este acuerdo: 1.- El elemento raíz se va a llamar "listapiezas". 2.- Dentro de "listapiezas" va a haber uno o muchos elementos "pieza" 3.- Dentro de "pieza" hay tres elementos: 3.1 Un elemento llamado "peso" que contiene datos. NO ES OBLIGATORIO QUE ESTÉ 3.2 Un elemento llamado "nombre" que contiene datos 3.3 Un elemento llamado fabricante que contiene datos. 3.3.1 El fabricante PUEDE LLEVAR un atributo llamado pais que indica el pais. Ejemplo de fichero válido .. code-block:: xml Pistón Asia Electronics 15 Cilindro Toyota Motors Ejemplo de fichero que debe dar errores .. code-block:: xml 20 Pistón 15 Toyota Motors Esquemas XML =========================================== Los esquemas XML son un mecanismo radicalmente distinto de crear reglas para validar ficheros XML. Se caracterizan por: * Estar escritos en XML. Por lo tanto, las mismas bibliotecas que permiten procesar ficheros XML de datos permitirían procesar ficheros XML de reglas. * Son mucho más potentes: ofrecen soporte a tipos de datos con comprobación de si el contenido de una etiqueta es de tipo ``integer``, ``date`` o de otros tipos. También se permite añadir restricciones como indicar valores mínimo y máximo para un número o determinar el patrón que debe seguir una cadena válida * Ofrecen la posibilidad de usar *espacios de nombres*. Los espacios de nombres son similares a los paquetes Java: permiten a personas distintas el definir etiquetas con el mismo nombre pudiendo luego distinguir etiquetas iguales en función del espacio de nombres que importemos. Un ejemplo ---------------- Supongamos que deseamos tener ficheros XML con un solo elemento llamado ```` que debe tener dentro un número. .. code-block:: xml 20 Un posible esquema sería el siguiente: .. code-block:: xml ¿Qué contiene este fichero? 1. En primer lugar se indica que este fichero va a usar unas etiquetas ya definidas en un espacio de nombres (o XML Namespace, de ahí ``xmlns``). Esa definición se hace en el espacio de nombres que aparece en la URL. Nuestro validador no descargará nada, esa URL es oficial y todos los validadores la conocen. Las etiquetas de ese espacio de nombres van a usar un prefijo que en este caso será ``xsd``. Nótese que el prefijo puede ser como queramos (podría ser "abcd" o "zztop"), pero la costumbre es usar ``xsd``. 2. Se indica que habrá un solo elemento y que el tipo de ese elemento es ````. Es decir, un entero básico. Si probamos el fichero de esquema con el fichero de datos que hemos indicado veremos que efectivamente el fichero XML de datos es válido. Sin embargo, si en lugar de una cantidad incluyésemos una cadena, veríamos que el fichero **no se validaría** Tipos de datos básicos ------------------------------ Podemos usar los siguientes tipos de datos: * ``xsd:byte``: entero de 8 bits. * ``xsd:short``: entero de 16 bits * ``xsd:int``: número entero de 32 bits. * ``xsd:long``: entero de 64 bits. * ``xsd:integer``: número entero sin límite de capacidad. * ``xsd:unsignedByte``: entero de 8 bits sin signo. * ``xsd:unsignedShort``: entero de 16 bits sin signo. * ``xsd:unsignedInt``: entero de 32 bits sin signo. * ``xsd:unsignedLong``: entero de 64 bits sin signo. * ``xsd:string``: cadena de caracteres en la que los espacios en blanco se respetan. * ``xsd:normalizedString``: cadena de caracteres en la que los espacios en blanco no se respetan y se reemplazarán secuencias largas de espacios o fines de línea por un solo espacio. * ``xsd:date``: permite almacenar fechas que deben ir **obligatoriamente** en formato AAAA-MM-DD (4 digitos para el año, seguidos de un guión, seguido de dos dígitos para el mes, seguidos de un guión, seguidos de dos dígitos para el día del mes) * ``xsd:time``: para almacenar horas en formato HH:MM:SS.C * ``xsd:datetime``: mezcla la fecha y la hora separando ambos campos con una T mayúscula. Esto permitiría almacenar ``2020-09-22T10:40:22.6``. * ``xsd:duration``. Para indicar períodos. Se debe empezar con "P" y luego indicar el número de años, meses, días, minutos o segundos. Por ejemplo "P1Y4M21DT8H" indica un período de 1 año, 4 meses, 21 días y 8 horas. Se aceptan períodos negativos poniendo -P en lugar de P. * ``xsd:boolean``: acepta solo valores "true" y "false". * ``xsd:anyURI``: acepta URIs. * ``xsd:anyType``: es como la clase ``Object`` en Java. Será el tipo del cual heredaremos cuando no vayamos a usar ningún tipo especial como tipo padre. La figura siguiente (tomada de la web del W3C) ilustra todos los tipos así como sus relaciones de herencia: .. figure:: tipos_xml_schema.png :figwidth: 50% :align: center Tipos en los XML Schemas Derivaciones ----------------- Prácticamente en cualquier esquema XML crearemos tipos nuevos (por establecer un símil es como si programásemos clases Java). Todos nuestros tipos tienen que heredar de otros tipos pero a la hora de "heredar" tenemos más posibilidades que en Java (dondo solo tenemos el "extends"). En concreto podemos heredar de 4 formas: 1. Poniendo restricciones (``restriction``). Consiste en tomar un tipo y crear otro nuevo en el que no se puede poner cualquier valor. 2. Extendiendo un tipo (``extension``). Se toma un tipo y se crea uno nuevo añadiendo cosas a los posibles valores que pueda tomar el tipo inicial. 3. Haciendo listas (``lists``). Es como crear vectores en Java. 4. Juntando otros tipos para crear tipos complejos (``union``). Es como crear clases Java en las que añadimos atributos de tipo ``int``, ``String``, etc... En general, las dos derivaciones más usadas con diferencia son las restricciones y las extensiones, que se comentan por separado en los puntos siguientes. Tipos simples y complejos ---------------------------- Todo elemento de un esquema debe ser de uno de estos dos tipos. * Un elemento es de tipo simple si no permite dentro ni elementos hijo ni atributos. * Un elemento es tipo complejo si permite tener dentro otras cosas (que veremos en seguida). Un tipo complejo puede a su vez tener contenido simple o contenido complejo: * Los que son de contenido simple no permiten tener dentro elementos hijo pero sí permiten atributos. * Los que son de contenido complejo sí permiten tener dentro elementos hijo y atributos. El diagrama siguiente refleja como funciona la estructuración de tipos de los XML Schema. .. figure:: esquema-tipos-w3c/Esquema-tipos.png :figwidth: 50% :align: center Tipos en los XML Schemas Así, por ejemplo un tipo simple que no lleve ninguna restricción se puede indicar con el campo ``type`` de un ``element`` como hacíamos antes: .. code-block:: xml Sin embargo, si queremos indicar alguna restricción adicional ya no podremos usar el atributo ``type``. Deberemos reescribir nuestro esquema así: .. code-block:: xml Aquí irán las restricciones, que hemos omitido por ahora. Ejercicio:edad de los trabajadores ----------------------------------- Se desea crear un esquema que permita validar la edad de un trabajador, que debe tener un valor entero de entre 16 y 65. Por ejemplo, este XML debería validarse: .. code-block:: xml 28 Pero este no debería validarse: .. code-block:: xml -3 La solución podría ser algo así: .. code-block:: xml Ejercicio: peso de productos ------------------------------ Se desea crear un esquema que permita validar un elemento peso, que puede tener un valor de entre 0 y 1000 pero aceptando valores con decimales, como por ejemplo 28.88 Una posible solución sería: .. code-block:: xml Ejercicio: pagos validados --------------------------- Crear un esquema que permita validar un elemento ``pago`` en el cual puede haber cantidades enteras de entre 0 y 3000 euros. .. code-block:: xml Ejercicio: validación de DNIs -------------------------------- Crear un esquema que permita validar un único elemento ``dni`` que valide el patrón de 7-8 cifras + letra que suelen tener los DNI en España: .. code-block:: xml Uniendo la herencia y el sistema de tipos -------------------------------------------- Llegados a este punto ocurre lo siguiente: * Por un lado tenemos que especificar si nuestros tipos serán simples o complejos (los cuales a su vez pueden ser complejos con contenido simple o complejos con contenido complejo). * Por otro lado se puede hacer herencia ampliando cosas (extensión) o reduciendo cosas (restricciones a los valores). Se deduce por tanto que no podemos aplicar todas las "herencias" a todos los tipos: 1. Los tipos simples no pueden tener atributos ni subelementos, por lo tanto **les podremos aplicar restricciones pero nunca la extensión**. 2. Los tipos complejos (independientemente del tipo de contenido) sí pueden tener otras cosas dentro por lo que **les podremos aplicar tanto restricciones como extensiones**. Restricciones ------------------ Como se ha dicho anteriormente la forma más común de trabajar es crear tipos que en unos casos aplicarán modificaciones en los tipos ya sea añadiendo cosas o restringiendo posibilidades. En este apartado se verá como aplicar restricciones. **Si queremos aplicar restricciones para un tipo simple las posibles restricciones son:** * ``minInclusive`` para indicar el menor valor numérico permitido. * ``maxInclusive`` para indicar el mayor valor numérico permitido. * ``minExclusive`` para indicar el menor valor numérico que ya no estaría permitido. * ``maxExclusive`` para indicar el mayor valor numérico que ya no estaría permitido. * ``totalDigits`` para indicar cuantas posibles cifras se permiten. * ``fractionDigits`` para indicar cuantas posibles cifras decimales se permiten. * ``length`` para indicar la longitud exacta de una cadena. * ``minLength`` para indicar la longitud mínima de una cadena. * ``maxLength`` para indicar la longitud máxima de una cadena. * ``enumeration`` para indicar los valores aceptados por una cadena. * ``pattern`` para indicar la estructura aceptada por una cadena. **Si queremos aplicar restricciones para un tipo complejo con contenido las posibles restricciones son las mismas de antes, pero además podemos añadir el elemento así como las siguientes.** * ``sequence`` para indicar una secuencia de elementos * ``choice`` para indicar que se debe elegir un elemento de entre los que aparecen. Atributos ----------------------- En primer lugar es muy importante recordar que **si queremos que un elemento tenga atributos entonces ya no se puede considerar que sea de tipo simple. Se debe usar FORZOSAMENTE un complexType**. Por otro lado en los XML Schema todos los atributos **son siempre opcionales, si queremos hacerlos obligatorios habrá que añadir un "required".** Un atributo se define de la siguiente manera: .. code-block:: xml Esto define un atributo llamado ``nombre`` que aceptará solo fechas como valores válidos y que además es obligatorio poner siempre. Ejercicios de XML Schemas ====================================== Cantidades limitades ------------------------ Crear un esquema que permita verificar algo como lo siguiente: .. code-block:: xml 20 Se necesita que la cantidad tenga solo valores aceptables entre -30 y +30. Solución a las cantidades limitadas ------------------------------------- La primera pregunta que debemos hacernos es ¿necesitamos crear un tipo simple o uno complejo?. Dado que nuestro único elemento no tiene subelementos ni atributos dentro podemos afirmar que solo necesitamos un tipo simple. Como aparentemente nuestro tipo necesita usar solo valores numéricos y además son muy pequeños nos vamos a limitar a usar un ``short``. Sobre ese ``short`` pondremos una restriccion que permita indicar los valores mínimo y máximo. .. code-block:: xml Este esquema dice que el elemento raíz debe ser ``cantidad``. Luego indica que es un tipo simple y dentro de él indica que se va a establecer una restricción teniendo en mente que se va a "heredar" del tipo ``short``. En concreto se van a poner dos restricciones, una que el valor mínimo debe ser -30 y otra que el valor máximo debe ser 30. Existe una alternativa más recomendable, que es separar los elementos de los tipos. De esa manera, se pueden "reutilizar" las definiciones de tipos. .. code-block:: xml Obsérvese que hemos puesto el tipo por separado y le hemos dado el nombre ``tipoCantidades``. El elemento raíz tiene su nombre y su tipo en la misma línea. Cantidades limitadas con atributo divisa ------------------------------------------ Se desea crear un esquema para validar XML en los que haya un solo elemento raíz llamado cantidad en el que se debe poner siempre un atributo "divisa" que indique en qué moneda está una cierta cantidad. El atributo divisa siempre será una cadena y la cantidad siempre será un tipo numérico que acepte decimales (por ejemplo ``float``). El esquema debe validar los archivos siguientes: .. code-block:: xml 20 .. code-block:: xml 18.32 Pero no debe validar ninguno de los siguientes: .. code-block:: xml 20 .. code-block:: xml abc Solución a las cantidades limitadas con atributo divisa --------------------------------------------------------- Crearemos un tipo llamado "tipoCantidad". Dicho tipo *ya no puede ser un simpleType ya que necesitamos que haya atributos*. Como no necesitamos que tenga dentro subelementos entonces este ``complexType`` llevará dentro un ``simpleContent`` (y no un ``complexContent``). Aparte de eso, como queremos "ampliar" un elemento para que acepte tener dentro un atributo obligatorio "cantidad" usaremos una ````. Así, el posible esquema sería este: .. code-block:: xml Cantidades limitadas con atributo divisa con solo ciertos valores ------------------------------------------------------------------- Queremos ampliar el ejercicio anterior para evitar que ocurran errores como el siguiente: .. code-block:: xml 18.32 Vamos a indicar que el atributo solo puede tomar tres posibles valores: "euros", "dolares" y "yenes". Solución al atributo con solo ciertos valores ------------------------------------------------- Ahora tendremos que crear dos tipos. Uno para el elemento ``cantidad`` y otro para el atributo ``divisa``. Llamaremos a estos tipos ``tipoCantidad`` y ``tipoDivisa``. La solución comentada puede encontrarse a continuación. Como puede verse, hemos includo comentarios. Pueden insertarse etiquetas ``annotation`` que permiten incluir anotaciones de diversos tipos, siendo la más interesante la etiqueta ``documentation`` que nos permite incluir comentarios. .. code-block:: xml A continuación creamos el tipo cantidad Como solo va a llevar atributos debemos usar un simpleContent Como queremos "ampliar" un tipo/clase para que lleve atributos usaremos una extension Ahora tenemos que fabricar el "tipoDivisa" que indica los posibles valores válidos para una divisa. Estas posibilidades se crean con una "enumeration". Nuestro tipo es un "string" y como vamos a restringir los posibles valores usaremos "restriction" Ejercicio: codigos y sedes --------------------------------- Se necesita tener un esquema que valide un fichero en el que hay un solo elemento llamado ``codigo`` * Dentro de código hay una cadena con una estructura rígida: 2 letras mayúsculas, seguidas de 2 cifras, seguidas a su vez de 3 letras. * El elemento ``código`` debe llevar un atributo ``sede`` que será de tipo cadena. Solución a los códigos y sedes ---------------------------------- Se nos piden dos cosas: 1. Restringir un tipo básico, en este caso el ``string`` 2. Extender una etiqueta para que tenga un atributo. Como no se puede hacer a la vez, deberemos dar dos pasos. Primero crearemos un tipo con la restricción y despues crearemos un segundo tipo con la extensión. **Cuando haya conflictos, siempre debemos crear primero la restricción y luego la extensión** Así, creamos primero esto: .. code-block:: xml Y despues lo ampliamos para que se convierta en esto: .. code-block:: xml Ejercicio: productos con atributos ----------------------------------- Se desea crear un esquema que permita validar un elemento raíz llamado ``producto`` de tipo ``xsd:string``. El producto tiene dos atributos: * Un atributo se llamará ``cantidad`` y es obligatorio. Debe aceptar solo enteros positivos. * También habrá un atributo llamado ``unidad`` que solo acepta los ``xsd:string`` "cajas" y "pales". .. code-block:: xml Ejercicio: clientes con información adicional ------------------------------------------------ Se desea crear un esquema XML que permita validar un elemento llamado ``cliente`` que puede almacenar un ``xsd:string``. El cliente contiene: * Un atributo obligatorio llamado ``codigo`` que contiene el código del cliente, que siempre consta de tres letras mayúsculas de tres números. * Un atributo optativo llamado ``habitual`` que se usará para saber si es un cliente habitual o no. Acepta valores "true" y "false". * Un atributo optativo llamado ``cantidad`` que indica su compra. Es un entero con valores de entre 0 y 1000. .. code-block:: xml Pepe Pérez Lista de clientes como XML Schemas ------------------------------------ En este apartado volveremos a ver un problema que ya resolvíamos con DTD: supongamos que en nuestros ficheros deseamos indicar que el elemento raíz es ````. Dentro de ```` deseamos permitir uno o más elementos ````. Dentro de ```` todos deberán tener ```` y ```` y en ese orden. Dentro de ```` puede aparecer o no un elemento ```` para indicar que ese cliente exige un máximo de plazo. Como no todo el mundo usa plazos el ```` es optativo. Vayamos paso a paso. Primero decimos como se llama el elemento raíz y de qué tipo es: .. code-block:: xml Ahora queda definir el tipo ``tipoListaClientes``. Este tipo va a contener un elemento (por lo que ya sabemos que es un ``complexType`` con ``complexContent`` dentro), y en concreto queremos que sea un solo elemento llamado ``cliente``, es decir **queremos imponer una restricción**. Aunque queramos un solo elemento tendremos que indicar una restricción. Como queremos permitir que el elemento pueda aparecer muchas veces utilizaremos un ``maxOccurs`` con el valor ``unbounded``. .. code-block:: xml Definamos ahora el tipo ``tipoCliente``. Dicho tipo **necesita tener subelementos dentro** así que evidentemente va a ser de tipo complejo. La pregunta es ¿es "tipo complejo con contenido simple" o "tipo complejo con contenido complejo"?. Si lo hiciéramos de "tipo complejo con contenido simple" podríamos tener atributos pero no subelementos, así que forzosamente tendrá que ser de un "tipo complejo con contenido complejo". Igual que antes impondremos una restricciones que es permitir solo que aparezcan ciertos elementos en cierto orden. El elemento ``plazo`` lo haremos optativo. .. code-block:: xml Si ahora probamos este XML veremos que el fichero se valida perfectamente a pesar de que es evidente que tiene errores. Es lógico, dado que no hemos aprovechado a fondo el sistema de tipos de XML para evitar que nadie suministre datos incorrectos en un XML. Dicha mejora la dejaremos para el siguiente ejercicio. .. code-block:: xml dd 20 dd 20 ABCD Ampliación del esquema para clientes ------------------------------------- Ahora ampliaremos el XML Schema del fichero anterior para que nadie suministre información incorrecta. En concreto tenemos tres datos: 1. El CIF, que vamos a presuponer que siempre tiene 8 cifras y al final una letra mayúsculas. Si alguna empresa tiene 7 cifras deberá incluir un 0 extra. 2. El nombre, que puede ser una cadena cualquiera. 3. El plazo, que debería ser un número positivo válido. Ahora, el fichero anterior no debería ser validado por el validador, pero sí debería serlo un fichero como este. .. code-block:: xml 01234567D Juan Sanchez 05676554A Pedro Diaz 45 La solución a los tres problemas indicados antes sería la siguiente: 1. El nombre puede ser una cadena cualquiera, por lo que tendrá que seguir siendo de tipo ``xsd:string``. Eso significa que si alguien introdujese un número en el nombre el fichero seguiría validándose. Por desgracia dicho problema no se puede resolver. 2. El plazo debería ser un número. Le asignaremos un tipo ``xsd:unsignedInt``. 3. El CIF es más complejo. Deberemos crear un tipo nuevo y establecer una restricción a los posibles valores que puede tomar. Así, una posible solución sería esta: .. code-block:: xml Ejercicio: lista de códigos ----------------------------- Se nos pide crear un esquema que permita validar un fichero como el siguiente: .. code-block:: xml AAA2DD BBB2EE BBB2EE En concreto, todo código tiene la estructura siguiente: 1. Primero van tres mayúsculas 2. Despues va exactamente un digito. 3. Por último hay exactamente dos mayúsculas. Un posible esquema XML sería el siguiente (obsérvese como usamos ``maxOccurs`` para indicar que el elemento puede repetirse un máximo de "infitas veces": .. code-block:: xml Ejercicio: otra lista de clientes ------------------------------------ Ahora se nos pide crear un esquema que permita validar un fichero como el siguiente, en el que hay una lista de clientes y el nombre es optativo, aunque los apellidos son obligatorios: .. code-block:: xml Juan Sanchez Jose Diaz La solución puede ser algo así: .. code-block:: xml Ejercicio: lista de alumnos ------------------------------------- Se desea construir un esquema para validar listas de alumnos en las que: * La raíz es ``listaalumnos``. * Dentro de ella hay uno o más ``alumno``. Todo ``alumno`` tiene siempre un atributo DNI que es obligatorio y que tiene una estructura formada por 7 u 8 cifras seguidas de una mayúscula. * Todo ``alumno`` tiene un elemento ``nombre`` y un ``ap1`` obligatorios. * Todo ``alumno`` puede tener despues del ``ap1`` un elemento ``ap2`` y uno ``edad``, ambos son optativos. * El elemento ``edad`` debe ser entero y positivo. (Gracias a Jesús VB por corregir una errata) Un ejemplo de fichero: .. code-block:: xml Jose Sanchez Andres Ruiz Ruiz 25 Y a continuación una posible solución: .. code-block:: xml Ejercicio: lista de articulos (con atributos optativos) ----------------------------------------------------------- Supongamos el fichero siguiente con las reglas que se explicitan en los comentarios: .. code-block:: xml CD12 Monitor CA12 AA99 Teclado A continuación se muestra una solución con un esquema que valida ficheros como el indicado: .. code-block:: xml Ejercicio: lista de componentes (un enfoque distinto) ------------------------------------------------------- Dado un archivo como el siguiente en el cual aparecen las reglas incluidas como comentarios, crear el esquema que valide la estructura de tales ficheros: .. code-block:: xml FAB1 Positiva 40.5 FAB2 260.5 Ahora en lugar de ir definiendo tipos empezando por el elemento raíz vamos a ir definiendo primero los tipos de los elementos más básicos que encontremos, e iremos construyendo los tipos más complejos a partir de los tipos fáciles que ya hayamos construido. Como veremos despues, el resultado va a ser el mismo. La solución: .. code-block:: xml n Ejercicio: listas con choice ----------------------------- Se pide elaborar un esquema que valide un fichero con las restricciones siguientes: * El elemento raíz es ``articulos``. Dicho elemento raíz debe llevar siempre un atributo ``fechaGeneración``. * Dentro de la raíz puede haber uno o varios de cualquiera de los siguientes elementos: ``monitor``, ``teclado`` o ``raton``. Cualquiera de los tres elementos puede llevar un atributo ``codigo`` que tiene siempre la estructura "tres letras, guión, tres letras, guión, tres cifras". Además, cualquiera de los tres debe llevar dentro y en primer lugar un elemento ``descripción`` que contiene texto. * Un monitor debe llevar (aparte de la descripción que va en primer lugar) un elemento ``resolución`` que a su vez debe llevar dentro dos elementos y en este orden ``ancho`` y ``alto``. Tanto ``ancho``, como ``alto`` deben llevar siempre dentro un entero positivo. * Un ``ratón`` debe llevar (aparte de la descripción que va en primer lugar) un elemento ``peso`` que siempre lleva dentro un entero positivo. Además, el ``peso`` lleva siempre dentro un atributo ``unidad`` que solo puede valer "g" o "cg". En el fichero siguiente se muestra un ejemplo .. code-block:: xml Monitor de x pulgadas... 1920 1400 Raton ergonomico... 100 Teclado estándar Monitor de x pulgadas... 1400 1000 Ejercicio: listas de productos -------------------------------- Se pide validar correctamente algo como esto: .. code-block:: xml Ordenador 23.44 17.50 17.50 Las reglas son: 1. Una lista de productos puede tener dentro muchos productos. 2. Todo producto tiene un "codigo" cuya estructura *dos mayúsculas seguidas de un guión seguido de dos o tres cifras* 3. Todo producto *puede tener (optativo)* un elemento descripción que es de tipo texto. 4. Todo producto **debe tener** un elemento peso que debe aceptar decimales pero que nunca puede ser negativo, es decir su valor mínimo es 0 La solución se muestra a continuación: .. code-block:: xml Ejercicio: validación de componentes -------------------------------------- Validar un fichero como este: .. code-block:: xml 2GB 190 14 99.49 Las reglas son las siguientes: 1. El elemento raíz se llama ``listacomponentes``. 2. Dentro de él puede haber uno o más elementos ``componente`` 3. Un componente puede ser una ``tarjetagrafica`` o un ``monitor``. 4. Un componente puede tener un atributo llamado ``codigo`` cuya estructura es siempre un dígito de 6 cifras. 5. Una tarjeta gráfica siempre tiene dos elementos llamados ``memoria`` y ``precio``. 6. La memoria siempre es una cifra seguido de GB o TB. 7. El tamaño del monitor siempre es un entero positivo. 8. El precio siempre es una cantidad positiva con decimales. El precio siempre lleva un atributo ``moneda`` que solo puede valer "euros" o "dolares" y que se utiliza para saber en qué moneda está el precio. La solución se muestra a continuación: .. code-block:: xml Ejercicio: inventario ------------------------ Varios administradores necesitan intercambiar información sobre inventario de material de oficina. Para ello, han llegado a un acuerdo sobre lo que se permite en un fichero XML de inventario. La idea básica es permitir ficheros como este: .. code-block:: xml 4.55 100 3.50 Las reglas concretas son estas: 1. Dentro de ```` puede haber uno de estos dos elementos hijo: un elemento ```` o un elemento ````. 2. Toda mesa tiene un elemento hijo ````. El peso siempre es un decimal positivo con dos cifras decimales. 3. Toda mesa tiene una ````. La superficie es un ``unsignedInt``. La superficie siempre tiene un atributo que puede ser solo una de estas dos cadenas: ``m2`` o ``cm2``. 4. Toda silla tiene siempre un ```` y las reglas de ese peso son exactamente las mismas que las reglas de ```` del elemento ```` La solución podría descomponerse de la forma siguiente: Resolvamos primero el problema de crear un tipo para el elemento ````. .. code-block:: xml Ahora resolvamos el problema del elemento ````. Para resolverlo, podemos aprovechar el tipo ``tipoPeso`` que acabamos de crear: .. code-block:: xml Ahora resolveremos el problema de la superficie: .. code-block:: xml Y apoyándonos en eso haremos la mesa: .. code-block:: xml Y ya solo queda indicar que un inventario es una lista de objetos (pondremos el ``maxOccurs`` a ``unbounded``) e indicaremos que un objeto puede ser una elección (````) entre dos tipos de objetos. .. code-block:: xml Ejercicio XML Schemas tipo examen (I) ======================================= Se necesita crear un esquema que controle la correcta sintaxis de ficheros con este estilo: .. code-block:: xml 2.212 -2.83 Petroleo -3.83 ENRON 2.91 Las reglas concretas son las siguientes: 1. El elemento raíz es ````. Dentro de él debe haber uno o más elementos ````. 2. Un ```` puede ser de tres tipos: ````, ```` y ````. 3. Todos los productos tienen siempre un elemento hijo llamado ```` que puede ser un número con dos decimales (puede ser positivo o negativo). 4. Todo ```` puede tener dentro un elemento llamado ```` que contiene un valor decimal que puede ser positivo o negativo y tener o no decimales. El elemento ```` deberá llevar dentro un atributo llamado ``moneda`` que solo puede tomar los valores ``dolares``, ``euros`` o ``yenes``. 5. Todo ```` tiene un hijo llamado ```` que puede contener dentro cadenas de cualquier tipo. Para saber en qué idioma está la cadena se usa un atributo llamado ``idioma`` que indica el idioma en el que está escrita la cadena. 6. Las acciones siempre tienen un elemento ```` que indica el nombre de la empresa y un atributo llamado ``país`` que indica de donde es la empresa. De momento queremos limitarnos a los países ``usa``, ``alemania``, ``japon`` y ``espana``. Recuérdese que siempre que no nos digan nada, se supone que un elemento o atributo es **obligatorio**. Si algo es optativo nos dirán "puede tener dentro", "puede contener", "puede aparecer", etc... Una posible solución sería esta: .. code-block:: xml Ejercicio XML Schemas tipo examen (II) =========================================== Crear una DTD que permita validar un fichero como el siguiente: .. code-block:: xml Oficina B09 i3 2 520 Las reglas son las siguientes: * El elemento raíz es ````. * Dentro de ```` debe haber un elemento ```` que lleva dentro una ```` o un ````. Todo ```` puede llevar un código que consta de dos letras y cuatro dígitos. Las letras podrían ser tanto mayúsculas como minúsculas. * Dentro de mesa puede haber (o no) un primer elemento ````. Despues debe haber un elemento ````. * Dentro de ordenador puede haber 3 elementos optativos pero que de aparecer lo hacen en el siguiente orden. * Primero un elemento ```` que puede llevar un atributo ``fabricante``. * Despues un elemento ```` que debe llevar obligatoriamente un atributo ``unidad``. * Despues un elemento ````. Una posible solución sería esta: .. literalinclude:: ejercicios/SolucionExamenII.xml :language: xml Ejercicio XML Schemas tipo examen (III) ======================================= Un distribuidor de alimentación necesita un fichero XML que almacene la información sobre pedidos recibidos y entregados que esté regido por un esquema XML que contemple las restricciones siguientes: * El elemento raíz se llama ``portes``. * Dentro de ``portes``, puede haber uno o más de los elementos ``recepcion`` y ``entrega``. Su orden puede ser aleatorio y el número de repeticiones también. * Un ``recepcion`` lleva dentro tres elementos: un elemento ``producto``, un elemento ``cantidad`` y un elemento ``codigoreceptor``. * El ``producto`` es obligatorio y lleva dentro texto. * El elemento ``cantidad`` (obligatorio) lleva dentro un número con decimales pero que debe ser siempre positivo. * El ``codigoreceptor`` lleva dentro un texto con la estructura: 3 cifras, guión, 3 letras (mayúsculas o minúsculas). Este elemento ``codigoreceptor`` es optativo. * Una ``entrega`` tiene siempre un atributo ``receptor`` que lleva dentro un texto. Aparte de eso, una ``entrega`` tiene siempre un elemento ``transportista`` que solo puede valer ``T1``, ``T2`` o ``T3``. Despues de el elemento ``transportista`` hay siempre un elemento ``distancia`` . La ``distancia`` es un numero mayor de 0. Es necesario que la ``distancia`` tenga un atributo ``unidad`` que indica la unidad en forma de cadena. Además una ``entrega`` lleva un atributo ``coste`` que siempre es un entero mayor de 0. A continuación se muestra un fichero de ejemplo .. code-block:: xml Fruta 125.5 333-AZT T2 468 Verdura 250 Una posible solución sería esta: .. literalinclude:: ejercicios/SolucionExamenIII.xml :language: xml Ejercicio XML Schemas tipo examen (IV) ======================================== Se propone el siguiente archivo de datos para una biblioteca: .. code-block:: xml Don Quijote de la Mancha Miguel de Cervantes Hamlet William Shakespeare Se desea un XML Schema que pueda hacer cumplir estas reglas. Una posible solución sería esta. .. code-block:: html Ejercicio XML Schemas tipo examen (V) ======================================== Se propone el siguiente fichero para el inventario de una empresa. .. code-block:: xml 719cf Libro electrónico 640 904ps 1499 Una posible solución sería esta: .. code-block:: xml Ejercicio XML Schemas tipo examen (V) ======================================== Un puerto necesita controlar las entradas y salidas de los muelles y para ello va a usar un fichero XML con unas reglas como estas. .. code-block:: xml B0143 Atenas Algeciras Oporto Amberes B0143 Una posible solución sería esta: .. code-block:: xml Ejercicio XML Schemas tipo examen (VI) ========================================= Se desea construir un esquema para verificar ficheros como el siguiente. Las reglas que se supone deben cumplir los datos se han adjuntado como comentarios en el propio fichero: .. code-block:: xml 192.168.1.10 Epson Windows