En la entrada anterior aprendimos sobre las DTD que, aunque siguen siendo muy útiles, su uso ha disminuido a favor de las definiciones de esquemas o XSD (schema definition) para definir la estructura de un documento XML y poder determinar si este es válido basado en reglas que nosotros mismos definimos. En esta entrada vamos a aprender las bases de los esquemas.
¿Esquema o DTD? Ventajas y desventajas
Técnicamente puedes elegir cualquiera de las dos opciones para definir archivos XML, sin embargo, ambas tienen sus ventajas y desventajas al momento de escoger una u otra. Las ventajas que podemos identificar de los esquemas sobre las DTD son:
- Con los esquemas podemos crear y trabajar con tipos de datos (decimales, long, short, etc.).
- Los espacios de nombre o namespaces son nativamente soportados por los esquemas. Con DTD es posible imitar la validación de estos pero el código necesario es considerablemente extenso.
- Si optas por utilizar esquemas, no necesitas aprender ningún lenguaje o metalenguaje extra ya que están escritos en XML, a comparación de las DTD que utilizan su propio metalenguaje.
La principal ventaja de las DTD frente a los esquemas es que estos últimos tienden a repetir muchas palabras en sus definiciones (concepto también conocido como verbose).
Creando un esquema
El primer elemento que necesitamos para un esquema es la raíz
<xs:schema> </xs:schema>
En seguida especificamos que los elementos y tipos de datos usados en el esquema serán los definidos por el espacio de nombres (namespace) del World Wide Web Consortium (W3C). Es obligatorio incluir esta etiqueta:
<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema">
Nosotros podemos crear nuestro propio espacio de nombres como en el ejemplo a continuación:
targetNamespace="codingornot"
Este atributo define el espacio de nombres por defecto:
xmlns="codingornot"
Finalmente, las siguientes declaraciones se usan para indicar si los elementos y atributos dentro del esquema necesitan ir precedidos del prefijo del espacio de nombres (el valor por defecto es “unqualified” que significa que no necesitan ir precedidos por el espacio de nombres):
elementFormDefault = "qualified" attributeFormDefault = "unqualified"
Nuestro elemento <xs:schema> quedaría como a continuación:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="codingornot" xmlns="codingornot" elementFormDefault="qualified"> </xs:schema>
Creando un elemento simple en XSD
Para crear una XDS o definición de esquema utilizamos la siguiente sintaxis:
<xs:element name="nombre-del-elemento" type="tipo-del-elemento">
Ejemplo:
<xs:element name="titulo" type="xs:string"/> <xs:element name="copias" type "xs:integer"/>
Los siguientes elementos son válidos analizándolos con el esquema anterior:
<titulo>Dragon Quest IX</titulo> <copias>15</copias>
Los esquemas permiten reconocer muchos tipos de datos, entre ellos tenemos:
xs:boolean xs:date xs:decimal xs:integer xs:string
Si quisiéramos declarar un valor por defecto:
<xs:element name="edad" type="xs:integer" default="18"/>
O valor obligatorio (automáticamente asignado al elemento):
<xs:element name="altura" type="xs:string" fixed="300px"/>
Elementos complejos
Un elemento complejo es aquel que puede contener otros elementos y/o atributos. Para declarar elementos complejos utilizamos complexType. Tomemos como ejemplo el siguiente elemento vacío:
<autor nombre="Fernando Fernandez">
Para validar el ejemplo anterior es necesario utilizar elementos complejos:
<xs:element name="autor" type="vaciotipocadena"/> <xs:complexType name="vaciotipocadena"> <xs:atribute name="nombre" type="xs:string"/> </xs:complexType>
Con definiciones como la anterior podemos validar elementos con estructuras similares como el siguiente (elemento vacío con un atributo cadena), ajustando name y type de ser necesario:
<xs:element name="apellido" type="vaciotipocadena">
Cuando queremos aceptar elementos que solamente contendrán subelementos (hijos) también es necesario usar elementos complejos. En dicho caso utilizamos
<xs:element name="videojuego" type="tipovideojuego"/> <xs:complexType name="tipovideojuego"> <xs:sequence> <xs:element name="titulo" type="xs:string"/> <xs:element name="desarrolladora" type="xs:string"/> </xs:sequence> </xs:complexType>
El fragmento anterior aceptará:
<videojuego> <titulo>Dragon Quest IX</titulo> <desarrolladora>Level 5</desarrolladora> </videojuego>
Para validarlo utilizamos un esquema como el siguiente para especificar que el elemento <videojuego>, además de una secuencia de elementos, también tendrá un atributo tipo cadena (string):
<xs:element name="videojuego" type="tipovideojuego"/> <xs:complexType name="tipovideojuego"> <xs:sequence> <xs:element name="titulo" type="xs:string"/> <xs:element name="desarrolladora" type="xs:string"/> </xs:sequence> <xs:attribute name="estado" type="xs:string"/> </xs:complexType>
Finalizando…
Espero que lo visto en esta entrada te haya servido. En la siguiente entrada continuaremos revisando más sobre esquemas. Hasta la próxima, see ya!