miércoles, 21 de septiembre de 2016

Más resúmenes y ejemplos sobre DTD

Definición de esquemas y vocabularios en XML

XML ha sido propuesto como estándar en el intercambio de información, independientemente de la plataforma en que se genere o se utilice. Esta premisa, en principio, es válida siempre y cuando los documentos XML no cambien durante los intercambios. Si en los intercambios de permite la modificación, adición o supresión de elementos de información, se ha de tener especial cuidado de no modificar la estructura del documento. No siempre es posible y puede llegar el caso en que el mismo documento pueda leerse en una aplicación y en otra no.
No solo es imprescindible que el documento esté bien formado (con las etiquetas de apertura y cierre bien ubicadas, que la codificación sea correcta, que los elementos cumplan la sintaxis de XML, etc), sino que ambos actores (emisor y receptor) se ciñan a un mismo formato de fichero definido previamente. Para evitar estos casos, se ha de definir una estructura fija del documento que conozcan las partes que intercambian la información.
A continuación, se mostrarán dos maneras de especificar formatos de comunicación en XML, las DTD y los XML Schema

DTD
DTD o Document Type Definition es la definición de cómo se construye un documento XML para que se ajuste a las necesidades previamente analizadas. Es decir, establece qué elementos son aceptados y en qué posiciones deben estar dentro de un documento XML
Cuando se define una DTD y se referencia dentro de un documento XML, se establece una relación de:
-          Qué léxico es el que se espera
-          Qué reglas sintácticas debe cumplir nuestro lenguaje
El significado semántico se proporciona en el uso del DTD y del docuemnto XML al generar las aplicaciones que lo utilizan.
Por tanto, antes de crear un documento XML se deberá analizar qué elementos y etiquetas se van a necesitar para la aplicación que se quiere crear. Para esto sirve una DTD
¿Por qué resulta importante la creación de DTD? Principalmente, cuando se analiza un almacenamiento de información en XML es porque esa información es importante compartirla. Pero aunque la compartición de la información pueda resultar interesante, la información debe estar sujeta a una serie de reglas para que todos los que lo utilicen(en consultas, inserciones, modificaciones, borrados, etc) y debe resultar bien formado y válido para el uso por terceras aplicaciones. Si en el proceso de acceso y modificación del documento XML se incumple su estructura, nos encontraremos con un documento no válido y con un futuro problema. Por tanto, una DTD permitirá asegurar que la información que contiene es válida y cumple los requisitos de intercambio de información entre personas con la misma DTD.
La creación de una DTD resulta muy simple:
  1. La DTD se puede ubicar dentro del propio documento XML
  2. La DTD se ubica en un fichero externo fuera del documento XML (Con extensión XML)

Ambas realizan la misma función pero resulta más cómoda utilizar un fichero externo para almacenar la DTD y realizar un enlace en el docuemnto XML para que la use. Además de la comodidad, existe otra ventaja fundamental: no se almacena en cada documento XML la DTD. Si tuviésemos muchos ficheros XML, basados en la misma especificación DTD, se tendría que cambiar en todos los ficheros la declaración de la DTD, cosa que si estuviera enlazado en un fichero externo, se cambiaría una única vez y todos los documentos XML lo aprovecharían. Además se estaría almacenando la misma información en todos los documentos, lo que aumentaría el tamaño del documento XML.
Para continuar, establezcamos un ejemplo en el que utilizar una DTD. Se quiere almacenar los mensajes de móviles que se envían a un servidor. Los datos se guardarán son los siguientes:
-          Número de teléfono del usuario
-          Fecha de envío
-          Hora de envío
-          Contenido del mensaje

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE BDsms SYSTEM “BDsms.dtd”>
<BDsms>
         <sms>
                   <telefono> 955 65 55 55 </telefono>
                   <fecha>1/7/2011</fecha>
                   <hora>23:55</hora>
                   <mensaje>Juego1: Tetris</mensaje>
         </sms>

         <sms>
                   <telefono>542 000 000</telefono>
                   <fecha> 10/11/2011</fecha>
                   <hora>09:22</hora>
                   <mensaje>Juego2: Comecocos</mensaje>
         </sms>
 </BDsms>


LA DTD que permite establecer el formato de intercambio de estos mensajes SMS, en el documento XML, podría ser el siguiente (fichero “BDsms.dtd”)
Notad que el fichero BDsms está referenciado en el documento XML. Si se quisiera incluir todo en el mismo documento XML, entonces quedaría:

<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE BDsms [
 <!ELEMENT BDsms (sms*)>
 <!ELEMENT sms (telefono, fecha, hora, mensaje)>
 <!ELEMENT telefono (#PCDATA)>
 <!ELEMENT fecha (#PCDATA)>
 <!ELEMENT hora (#PCDATA)>
 <!ELEMENT mensaje (#PCDATA)>
 ]>

 <BDsms>

         <sms>
                   <telefono> 955 65 55 55 </telefono>
                   <fecha>1/7/2011</fecha>
                   <hora>23:55</hora>
                   <mensaje>Juego1: Tetris</mensaje>
         </sms>

         <sms>
                   <telefono>542 000 000</telefono>
                   <fecha> 10/11/2011</fecha>
                   <hora>09:22</hora>
                   <mensaje>Juego2: Comecocos</mensaje>
         </sms>
 </BDsms>

Bloques para construir una DTD
Viendo el ejemplo de la base de datos de SMS, se puede observar una serie de elementos definidos en una DTD:
-          Elemento. Es el bloque principal con el que se construyen los elementos DTD
-          Atributo: Forma de añadir más información a un elemento
-          Entidad. En XML existen algunos caracteres que tienen un significado especial. La aparición de estos caracteres como datos almacenables hace que se puedan confundir con entidades propias de un documento XML. Son entidades las siguientes:
o   &nbsp; => Espacio en blanco
o   &gt; => >
o   &lt; => <
o   &quot => “
o   &apos; => ‘
o   &amp; => &
-          Se pueden usar dentro del propio documento XML y tras parsear el documento tomarán el valor indicado a la derecha. También el usuario puede definir entidades propias para que, después de analizar el documento XML, se sustituyan por el valor indicado. Es como una especie de definición preestablecida. Un par de ejemplos son los siguientes:
o   <!ENTITY pi “3.14.15.92”> => &pi;
o   <!ENTITY textFile SYSTEM “fichero.txt”>  =>&textFile
o   <!ENTITY miURL SYSTEM http://www.as.com> => miURL
-          PCDATA. Su significado en inglés es Parsed Character Data. Indica que entre la etiqueta y cierre de apertura de ese elemento, se almacenarán caracteres como texto y serán analizados por un parser. Como es lógico, al analizarse mediante el parser el contenido del texto para encontrar entidades y elementos, si es solo texto no podrá encontrarse ninguno de los caracteres anteriormente mencionados (pues podría confundir al parser a la hora de analizar el documento XML)
-          CDATA.. Su significado en inglés Character Data. A efectos es prácticamente igual que PCData pero el contenido de ese elemento, entre sus etiquetas de apertura y cierre, no se analizará por el parser de análisis de entidades y elementos XML.
Los elementos se declaran de una de las dos siguientes maneras:
<!ELEMENT nombre_del_elemento categoría>
O
<!ELEMENT nombre_del_elemento (nodos_hijos)>
En el segundo caso se pueden definir el nombre_del_elemento como el nodo padre del que cuelgan un conjunto de nodos hijos (separados por comas)
Si existiera algún elemento que deba estar vacío, existe la palabra reservada EMPTY que puesta en la zona de “categoría” permite indicar este hecho. Un ejemplo de uso es la etiqueta <br> de HTML. Esta etiqueta permite establecer un salto de línea pero debería estar indicado como <br></br>. Si se declara como EMPTY, entonces se podría simplificar el salto de línea de la siguiente manera :<br />
<!ELEMENT saltoLinea EMPTY> => <saltoLinea />
<!ELEMENT telefono (#PCDATA)>
<!ELEMENT hora (#CDATA)>
En el caso concreto de ANY, permite indicar que cualquier combinación de elementos conocidos serían válidos en ese caso.

<!ELEMENT hora (#ANY)> => Podría valer teléfono, fecha, mensaje,…

No se ha comentado nada, hasta el momento, sobre los atributos. La manera de declararlos en un DTD es mediante la siguiente sintaxis:

<!ATTLIST nombre_elemento nombre_atributo tipo_atributo valor_por_defecto>

-          Nombre_elemento: es el elemento al que se le quiere añadir el atributo.
-          Nombre_atributo: es el nombre del atributo que se quiere añadir.
-          Tipo_atributo: existen muchos tipos de atributos destacan:
o   CDATA: es un texto. Podrán tener cualquier carácter
o   ID: Es un identificador que permite identificar el elemento de manera única en todo documento XML
o   IDREF: Es un identificador de otro elemento del propio documento XML
o   IDREFS: Es una lista de identificadores a otros elementos (tipo1 | tipo2 | tipo3 | …) el valor es uno de los indicados en esta lista enumerada  (definida por el usuario).
o   NMTOKEN: Es un texto que solo podrá tener letras, dígitos, guión, “-“, punto, “.”, y dos puntos “:”. Es lo que se llama nombres válidos XML
o   NMTOKENS: Es una lista de nombres XML válidos. Es como un NMTOKEN pero se incluyen los espacios en blanco, “ “, tabuladores o retornos del carro.
o   ENTITY: El tipo de atributo es una entidad que se ha declarado anteriormente
o   ENTITIES: Es una lista de entidades

Los atributos podrán ser declarados como obligatorios #REQUIRED, optativos, #IMPLIED o fijos #FIXED. Este último obliga al usuario que el atributo sea siempre el mismo, sin que pueda cambiarlo (si se cambia no estaría conforme a la DTD declarada y devolvería un error)
Como no se ha declarado ningún atributo en el ejemplo de los SMS, cambiaremos el elemento hora para añadir la zona o franja horaria (de manera obligatoria). Se quiere tener un documento XML de este tipo:
….
         <hora zona=”GMT+1”>09:22</hora>
.…
Por lo que el DTD debe añadir la siguiente línea:
<!ATTLIST hora zona CDATA “GMT+1” #REQUIRED>

Secuencias de elementos: Estructura con hijos
Podemos ver que el elemento sms está compuesto por teléfono, fecha, hora y mensaje. Esta es una relación padre-hijos. Imaginemos que una vez definida una DTD, nos damos cuenta que, por cada SMS recibido se pueden almacenar varios mensajes. En este caso debería cambiar la ocurrencia de la aparición de los elementos justo cuando los indicamos en el elemento padre. Las ocurrencias que pueden aparecer se indican con los siguientes operadores:
-          “: Indica que aparece obligatoriamente una vez. Es el caso inicial en cuanto se declara un hijo al elemento sms.
-          “+”: indica que puede haber una o más ocurrencias del elemento indicado
o   <!ELEMENT sms (teléfono, fecha, hora, mensaje+)>
-          “*”: Indica que puede haber cero o más ocurrencias del elemento indicado
o   <!ELEMENT sms (teléfono, fecha, hora, mensaje*)>    
-          “?”: indica que puede haber cero o una ocurrencia del elemento indicado (también llamado opcionalidad)
o   <!ELEMENT sms (teléfono, fecha, hora, mensaje?)>

No solo se pueden cambiar las ocurrencias de los hijos declarados, sino que podemos indicar la opcionalidad de la aparición de hijos. En este caso podríamos definir que querremos almacenar o la hora o el mensaje pero no las dos simultáneamente pero sí obligatoriamente una de las dos, por lo que quedaría así:
<!ELEMENT BDsms (sms*)>
<!ELEMENT sms (telefono, fecha, (hora | mensaje)>
<!ELEMENT telefono (#PCDATA)>
<!ELEMENT fecha (#PCDATA)>
<!ELEMENT hora (#PCDATA)>
<!ELEMENT mensaje (#PCDATA)>

Ejemplo.
Se quiere crear una biblioteca de libros en un documento XML. Para ello, se necesita crear una DTD que almacene los siguientes campos de un libro:
  1. Código del libro
  2. Título
  3. Editorial
  4. Edición
  5. ISBN
  6. Número de páginas
  7. Autor

Como DTD incrustada         :

<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE biblioteca [
 <!ELEMENT biblioteca (libro*)>
 <!ELEMENT libro (codigo, titulo, Editorial, Edicion, ISBN, Numero_de_paginas, Autor)>
 <!ELEMENT codigo (#PCDATA)>
 <!ELEMENT titulo (#PCDATA)>
 <!ELEMENT Editorial (#PCDATA)>
 <!ELEMENT Edicion (#PCDATA)>
 <!ELEMENT ISBN (#PCDATA)>
 <!ELEMENT Edición (#PCDATA)>
 <!ELEMENT Numero_de_paginas (#PCDATA)>
 <!ELEMENT Autor (#PCDATA)>
 ]>
 <biblioteca>

         <libro>
                   <codigo>
                   001
                   </codigo>
                   <titulo>
                   El Oscuro PAsajero
                   </titulo>
                   <Editorial>
                   Umbriel
                   </Editorial>
                   <Edicion>
                   La primera
                   </Edicion>
                   <ISBN>
                   84-95618-83-4
                   </ISBN>
                   <Numero_de_paginas>
                   251
                   </Numero_de_paginas>
                   <Autor>
                   Jeff Lindsay
                   </Autor>
         </libro>
</biblioteca>

Si lo validamos en la dirección http://www.xmlvalidation.com/
Podemos comprobar que se valida sin problemas:


¿Cómo hacer la validación para incluir esta misma información de  DTD desde un fichero externo?
Antes que nada debemos separar los dos ficheros que tendremos ahora, biblioteca.xml y biblioteca.dtd:

Primer fichero biblioteca.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE biblioteca SYSTEM "biblioteca.dtd">
<biblioteca>

         <libro>
                   <codigo>
                   001
                   </codigo>
                   <titulo>
                   El Oscuro PAsajero
                   </titulo>
                   <Editorial>
                   Umbriel
                   </Editorial>
                   <Edicion>
                   La primera
                   </Edicion>
                   <ISBN>
                   84-95618-83-4
                   </ISBN>
                   <Numero_de_paginas>
                   251
                  </Numero_de_paginas>
                   <Autor>
                   Jeff Lindsay
                   </Autor>
         </libro>
</biblioteca>

Segundo fichero biblioteca.dtd

<!ELEMENT biblioteca (libro*)>
 <!ELEMENT libro (codigo, titulo, Editorial, Edicion, ISBN, Numero_de_paginas, Autor)>
 <!ELEMENT codigo (#PCDATA)>
 <!ELEMENT titulo (#PCDATA)>
 <!ELEMENT Editorial (#PCDATA)>
 <!ELEMENT Edicion (#PCDATA)>
 <!ELEMENT ISBN (#PCDATA)>
 <!ELEMENT Edición (#PCDATA)>
 <!ELEMENT Numero_de_paginas (#PCDATA)>
 <!ELEMENT Autor (#PCDATA)>

Para validar ambos elementos, ahora procedemos a la dirección anterior:

Cargamos en primer lugar el archivo xml. Después hacemos clic en validar
Y nos aparece lo siguiente:


Aquí nos está informando de que el archivo tiene una referencia a una dtd y que para validar ambas, debemos incluir a continuación el contenido del archivo dtd. Lo hacemos:

 

Y, tras hacer clic en “continue validation” (Continuar validación)

Nos dice lo siguiente:



No hubo errores encontrados, así que nuestros documentos, tanto DTD como XML están bien formados y, además, son válidos.



No hay comentarios:

Publicar un comentario