Creando+un+DTD+para+las+recetas

**Introducción .- ** En el anterior articulo sobre concepto del modelo de contenido de Dorothy Hoskins nos dimos cuenta de la importancia de crear una estructura DTD que nos permita unificar los criterios en el momento de generar nuevas recetas de cocina, de manera que sean validables por algún sistema informático.
 * Creando un DTD para las recetas **

**Proceso .- ** Para elaborar un DTD que nos sirva para validar las recetas de cocina para nuestro libro, partiremos de los siguientes elementos :
 * Un editor para crear el fichero DTD:por ejemplo Editix . ( Para descargar pulsar aquí)
 * Fichero XML con la receta de cocina inicial Besugo al horno Descargar pulsando aquí]
 * Articulo sobre concepto del modelo de contenido de Dorothy Hoskins
 * Un pequeño videotutorial : https://www.youtube.com/watch?v=EfnWCeQNTQI de Sergio Lujan Mora
 * Un tutorial con la documentación basica :http://www.jorgesanchez.net/web/lmsgi/LMSGI02.pdf de Jorge Sanchez Asenjo

**Preparación:- ** 1.- Desde el editor ( Editix), abriremos el fichero XML (receta0.xml) y visualizaremos la estructura en forma de arbol para simplificar el proceso . 2.- Una vez abierto el documento DTD, seleccionaremos el **Menú "DTD/Schema" [1]** luego la opción **"Generate" [2]**, a continuación "**DTD From de Document" [3]** y nos abrirá una ventana con la estructura del documento, donde nos aparecerá la etiqueta raíz (recetas) [4] y dentro de recetas el elemento "receta" [5]. seleccionamos este elemento y pulsamos OK [6]
 * Desarrollo.- **



3.- El asistente nos creara un documento DTD a partir de la estructura de nuestro documento XML, pero que como veremos requerirá de nuestra definitiva definición:

**Definición de los elementos y atributos ** <span style="font-family: Verdana,Geneva,sans-serif; font-size: 130%;">Vamos a ir definiendo los distintos elementos y atributos del fichero XML siguiendo la definición DTD, pero también analizando, //**que elementos que no están presentes en esta receta podrían ser susceptibles de incorporarse**// a otras recetas nuevas que queramos crear a partir de este modelo. **1.- Elemento raiz (recetas) :** **<!ELEMENT recetas ( receta )>** La lectura de esta definición es que la etiqueta raíz se llama **recetas** y esta formada por elementos llamados **receta**. Aquí debemos preguntarnos:
 * Siempre existirá una receta como mínimo, y que pueden existir mas, por ello usaremos "+" que obliga a un mínimo de una presencia pero que pueden existir más de una vez

Modificación: **<!ELEMENT recetas ( receta+ )>** Significa que pueden existir una o mas recetas pero como mínimo una receta.

**2.- Elemento receta:** ** <!ELEMENT receta ( nombre, categoria , informacion_general , ingredientes , preparacion )> ** En esta definición indicamos que el elemento receta esta formado por otros elementos en el orden especificado. Haremos el siguiente análisis:
 * Primero revisaremos el orden de los elementos : que en este caso coincide con el del fichero XML que tenemos de patrón: nombre, categoria , informacion_general , ingredientes , preparación
 * Revisaremos elemento por elemento si debe estar o no presente y si pueden existir mas de un elemento con la misma etiqueta:
 * nombre = Solo un nombre y siempre presente
 * categoria = Siempre presente, pero podría tener mas de una categoría, por ejemplo ser un entrante o unos postre. Por tanto añadiremos "+"
 * informacion_general = Siempre presente y solo una, aunque dentro contenga diversos elementos
 * ingredientes = Mínimo uno pero normalmente varios. Añadiremos "+"
 * preparacion = Mínimo un proceso de preparación pero normalmente varios. Añadiremos "+"
 * Que elementos importantes podemos añadir que no estaban `presentes en nuestro patrón ? Pues puede resultar casi imprescindible la referencia sobre el autor/a. Añadiremos "**autor+**" pues la receta puede estar redactada por diversos autores, puede optarse por el valor "anónimo" para casos de autor/a desconocido.

Modificación: **<!ELEMENT receta ( nombre,categoria+,autor+,informacion_general,ingredientes+,preparacion+ )>** Podemos optar por añadir el atributo "**idioma**" dentro de la etiqueta **receta** y a la vez acotar la codificación de los idiomas que habitualmente se usaran, y tambien asignaremso que sea una información de presencia obligada, .de manera que añadiremos el atributo idioma de la siguiente manera: **<!ATTLIST receta idioma (es_ES | ca_ES | eu_ES | gl_ES | en_US | fr_FR | pt_PT ) #REQUIRED >** **3.- Elemento nombre:** ** <!ELEMENT nombre ( #PCDATA )> ** En esta definición indicamos que el elemento nombre podrá contener texto literal tan largo como se desee.

** <!ELEMENT categoria ( #PCDATA )> ** En esta definición indicamos que el elemento nombre podrá contener texto literal tan largo como se desee. Recordemos que hemos definido que en nuestra receta podemos asignar dos categorías a un plato. Otra variable que podemos incorporar es la de tener definidas las posibles categorías de manera que para una gestión desde múltiples usuarios será mucho mas fiable tener controladas las diversas posibilidades para evitar incongruencias de asignar nombres distintos para la misma categoría En nuestro caso definiremos las siguientes categorías:.
 * 4.- Elemento categoria:**
 * Arroces
 * Aves
 * Carne
 * Ensaladas
 * Entrante
 * Legumbres
 * Pasta
 * Pescado
 * Postre
 * Primeros
 * Reposteria
 * Segundos
 * Sopas
 * Verduras

Modificación: ** <!ELEMENT categoria ( Arroces | Aves | Carne | Ensaladas | Entrante | Legumbres | Pasta | Pescado | Postre | Primeros | Reposteria | Segundos | Sopas | Verduras ) > ** **5.- Elemento autor:**** <!ELEMENT autor ( #PCDATA )> **  Haremos el tratamiento de las distintas referencias del autor/a, como atributos de la etiqueta autor, por lo que si existen diversos autores, cada autor/a tendrá las referencias dentro de su etiqueta,dada la variabilidad de posibilidades estas referencia serán siempre optativas y como máximo una para cada atributo. ** <!ATTLIST autor mail CDATA #IMPLIED > ** **6.- Elemento informacion_general:** ** <!ELEMENT informacion_general ( foto, comensales , tiempo , dificultad )> ** En este caso informacion_general, contiene cuatro elementos que vamos a analizar
 * <!ATTLIST autor foto_autor CDATA #IMPLIED > **
 * <!ATTLIST autor url CDATA #IMPLIED > **
 * <!ATTLIST autor tweeter CDATA #IMPLIED > **
 * <!ATTLIST autor linkedin CDATA #IMPLIED > **
 * <!ATTLIST autor facebook CDATA #IMPLIED > **
 * foto = Indicaremos la url de la imagen, en este caso sera de tipo CDATA porque debe permitir símbolos especiales que pueden estar contenidos en la url y que no serán filtrados, mientras que con #PCDATA estos símbolos son filtrados, será obligatoria y puede no contener ninguna imagen, una o más de una imagen de la receta. por ello tendremos presente añadir "*"
 * comensales = Solo habrá un elemento y indicaremos el numero concreto de comensales, por tanto será de tipo PCDATA
 * tiempo= Solo habrá un elemento y contendrá el atributo unidad para especificar en que unidades medimos el tiempo
 * dificultad = Solo habrá un elemento y usaremos para indicar el nivel de dificultad, Se presta a preestablecer los niveles definidos de posible dificultad
 * Posibles nuevas etiquetas : Dado que no están en todas las recetas lo especificamos con el símbolo "?" para los casos de presencia nula o 1 vez y si pueden no existir o existir una o mas veces usaríamos "*"
 * coste = Indicaríamos un coste aproximado por comensal

Modificación: ** <!ELEMENT informacion_general ( foto*, comensales , tiempo , dificultad, coste? )> **

** <!ELEMENT foto ( #PCDATA )> ** Para este elemento solo añadiremos el "+" indicativo de que puede repetirse Modificación: ** <!ELEMENT foto ( #PCDATA ) > ** Este elemento ya lo dejamos como está
 * 7.- Elemento foto:**
 * 7.- Elemento comensales:**
 * <!ELEMENT comensales ( #PCDATA )> **

Vemos que para el tiempo usamos un atributo "**unidad**" que nos indicara en que unidades hemos medido el tiempo, el valor sera un carácter de cualquier tipo no evaluable por el procesador XML (**CDATA)**, y que ademas el dato debe estar presente para ello usamos el **#REQUIRED** En este caso podríamos acotar las posibles unidades de tiempo para armonizar mejor las distintas recetas con orígenes diferentes Por ello vamos a considerar como posibles unidades de tiempo : minutos, horas, dias lo indicaremos de manera **( minutos | horas | dias )** el resultado final será :
 * 8.- Elemento tiempo:**
 * <!ELEMENT tiempo ( #PCDATA )> **
 * <!ATTLIST tiempo unidad CDATA #REQUIRED > **

Modificación: ** <!ELEMENT tiempo ( #PCDATA )> **
 * <!ATTLIST tiempo unidad (minutos | horas | dias ) #REQUIRED > **

Vamos a codificar los posibles valores de este parámetro: ( Muy baja | Baja | Normal | Alta | Muy Alta )
 * 9- Elemento dificultad:**
 * <!ELEMENT dificultad ( #PCDATA )> **

Modificación: ** <!ELEMENT dificultad ( Alta | Normal | Baja ) > ** Este elemento añadido hemos indicado que será opcional i en caso de estar presente solo una vez, por ello usamos el **"?".** Tendrá también un atributo que llamaremos "**moneda**" y será la moneda de calculo, para ello acotaremos a dos monedas **(dolar | euro)** en caso de existir coste si que será obligatoria la moneda por ello indicaremos **#REQUIRED** y por defecto si no indicamos moneda esta será el dolar, lo indicaremos al final después el #REQUIRED El resultado siguiendo el ejemplo del tiempo será:
 * 10.- Elemento añadido = coste :**
 * <!ELEMENT coste ( #PCDATA ) > **
 * <!ATTLIST coste moneda ( dolar | euro ) #REQUIRED dolar > **

** <!ELEMENT ingredientes ( ingrediente+ )> ** Indicamos que el elemento ingredientes contendrá uno o mas elementos de nombre ingrediente, por ello indicamos el símbolo "+" que significa como presencia uno o más ingredientes **12.- Elemento ingrediente :**
 * 11.- Elemento ingredientes :**
 * <!ELEMENT ingrediente ( #PCDATA )> **
 * <!ATTLIST ingrediente cantidad CDATA #IMPLIED > **
 * <!ATTLIST ingrediente unidad CDATA #IMPLIED > **

Para cada ingrediente tenemos definida la **cantidad** y la **unidad** usada como atributos, pero estos pueden no estar presentes por ello les asignamos el #IMPLIED. Podríamos acotar las unidades de medida, pero en el caso de los ingredientes se hace muy complicado debido a que los cocineros utilizan muchos tipos de medida a menudo en función de los utensilios presentes en la cocina.

Indicamos que el elemento preparación puede tener uno o mas pasos
 * 13.- Elemento preparacion :** ** <!ELEMENT preparacion ( paso+ )> **


 * 14.- Elemento paso:**

** <!ELEMENT paso ( #PCDATA )> ** Vemos que cada paso tiene un atributo numero que lo identifica y que es obligatorio, por ello tiene asignado el #REQUIRED
 * <!ATTLIST paso numero CDATA #REQUIRED > **

//**<!ELEMENT recetas (receta+)>**// //**<!ELEMENT receta (nombre,categoria+,autor+,informacion_general,ingredientes+,preparacion+ )>**// //**<!ATTLIST receta idioma (es_ES | ca_ES | eu_ES | gl_ES | en_US | fr_FR | pt_PT ) #REQUIRED >**// //**<!ELEMENT nombre (#PCDATA )>**// //**<!ELEMENT categoria ( Arroces | Aves | Carne | Ensaladas | Entrante | Legumbres | Pasta | Pescado | Postre | Primeros | Reposteria | Segundos | Sopas | Verduras ) >**// //**<!ELEMENT autor (#PCDATA) >**// //**<!ATTLIST autor mail CDATA #IMPLIED >**// //**<!ATTLIST autor foto_autor CDATA #IMPLIED >**// //**<!ATTLIST autor url CDATA #IMPLIED >**// //**<!ATTLIST autor tweeter CDATA #IMPLIED >**// //**<!ATTLIST autor linkedin CDATA #IMPLIED >**// //**<!ATTLIST autor facebook CDATA #IMPLIED >**// //**<!ELEMENT informacion_general ( foto*, comensales , tiempo , dificultad,coste? )>**// //**<!ELEMENT foto ( #PCDATA )>**// //**<!ELEMENT comensales ( #PCDATA )>**// //**<!ELEMENT tiempo ( #PCDATA )>**// //**<!ATTLIST tiempo unidad ( minutos | horas | dias ) "minutos" >**// //**<!ELEMENT dificultad ( Profesional | Difícil | Moderada | Fácil ) >**// //**<!ELEMENT coste ( #PCDATA ) >**// //**<!ATTLIST coste moneda ( dolar | euro ) #REQUIRED >**// //**<!ELEMENT ingredientes ( ingrediente+ )>**// //**<!ELEMENT ingrediente ( #PCDATA )>**// //**<!ATTLIST ingrediente cantidad CDATA #IMPLIED >**// //**<!ATTLIST ingrediente unidad CDATA #IMPLIED >**// //**<!ELEMENT preparacion ( paso+ )>**// //**<!ELEMENT paso ( #PCDATA )>**// //**<!ATTLIST paso numero CDATA #REQUIRED >**//

**<span style="color: #30d334; font-family: Verdana,Geneva,sans-serif; font-size: 150%;">Testear la sintaxis gramatical del DTD .- ** <span style="font-family: Verdana,Geneva,sans-serif; font-size: 20.8px;">Si usamos Editix, la misma aplicación nos facilitará analizar el fichero DTD creado para validar la sintaxis del mismo. En este caso vamos al Menú DTD/Schema [1] luego seleccionamos Check this DTD [2] y obtendremos la validación sintáctica del DTD que hemos creado [3]

==

== <span style="font-family: Verdana,Geneva,sans-serif; font-size: 130%;">Podemos también testar el DTD on-line en paginas como : @http://www.validome.org/xml/ <span style="font-family: Verdana,Geneva,sans-serif; font-size: 130%;">en este caso los pasos a seguir són:
 * 1) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 130%;">Copiar y pegar el código DTD generado
 * 2) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 130%;">Indicamos que queremos validación por DTD
 * 3) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 130%;">Pulsamos el botón de "Validate"
 * 4) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 130%;">Finalmente si la sintaxis es válida nos aparece el mensaje



**<span style="color: #30d334; font-family: Verdana,Geneva,sans-serif; font-size: 150%;">Verificar el XML .- ** <span style="font-family: Verdana,Geneva,sans-serif; font-size: 20.8px;">En este caso lo que queremos es comprobar si el XML que tenemos cumple las reglas descritas en el DTD creado. Para ello deberemos relacionar los dos documentos por un lado el XML y del otro el DTD. Existen diversas opciones pero nos centraremos en la mas operativa. <span style="font-family: Verdana,Geneva,sans-serif; font-size: 20.8px;">Vamos pues a optar por esta 3a opción. Para ello realizaremos los siguientes pasos: >> <span style="display: block; font-family: Verdana,Geneva,sans-serif; font-size: 130%; text-align: center;">@http://androidtech.comuv.com/receta/receta.dtd >>
 * 1) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 20.8px;">Podemos añadir el DTD dentro del mismo documento XML. pero en este caso el DTD solo servirá para este fichero XML y no podemos ni modificar ni aplicar a otros ficheros XML.
 * 2) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 20.8px;">Podemos gravar el DTD en un fichero externo que estará accesible al fichero XML pero de manera local En este caso nuestro DTD podrá servir para validar a otros ficheros XML de la propia empresa de la misma red
 * 3) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 20.8px;">Podemos gravar el DTD en un fichero expuesto de manera pública en Internet y accesible para todas las personas que quieran usar nuestra definición. Justamente deberíamos tender a este tipo de funcionamiento de manera que nuestro trabajo podría ser aprovechado por otras personas que también quieran tener sus propias recetas, de manera que nuestros datos podrian ser intercambiados o reunidos en un mismo fichero de datos.
 * 1) <span style="font-family: Verdana,Geneva,sans-serif; font-size: 20.8px;">Subiremos a nuestro hosting de Internet el fichero DTD y le daremos permisos de acceso. En nuestro caso la url serà :
 * 1) <span style="display: block; font-family: Verdana,Geneva,sans-serif; font-size: 20.8px; text-align: left;">Indicaremos en nuestro XML la localización del fichero que contiene las normas DTD. Podemos usar varias sintaxis para este menester, si usamos **<!DOCTYPE nombre SYSTEM "uri">**, en este caso al usar SYSTEM hacemos que el DTD solo se use para un documento concreto, es decir que no puede compartirse. En nuestro caso utilizaremos la sintaxis :

**<span style="color: #208090; font-family: Verdana,Geneva,sans-serif;"><!DOCTYPE recetas SYSTEM "http://androidtech.comuv.com/receta/receta.dtd"> ** <span style="display: block; font-family: Verdana,Geneva,sans-serif; font-size: 20.8px; text-align: left;"> Añadiremos la linea de validación como segunda linea del XML : <span style="display: block; font-family: Verdana,Geneva,sans-serif; font-size: 20.8px; text-align: left;"> <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;"><?xml version="1.0" encoding="UTF-8"?> <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;"> <!DOCTYPE recetas SYSTEM "http://androidtech.comuv.com/receta/receta.dtd"> <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;"> <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;"> <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;"> Besugo al horno <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;">... <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;">... <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;"> <span style="font-family: Verdana,Geneva,sans-serif; font-size: 18.8px;">