===
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