03. XML: XSD Definición de esquemas (schemas) parte 2

Publicado por

En la entrada anterior (enlace a entrada anterior) comenzamos revisando sobre XSD o definiciones de esquemas (schemas). En esta entrada continuaremos revisando algunos temas no vistos en la entrada anterior.

Elementos mixtos

Un elemento mixto es aquel que puede contener texto plano mezclado con las etiquetas y atributos en el XML. Pueden ser muy útiles cuando nuestra intención es transmitir un mensaje como a continuación:

<analisis>

El videojuego <titulo>Dragon Quest</titulo> desarrollado por <desarrolladora>Level 5</desarrolladora> es uno de los mejores juegos del grupo de desarrolladores. Lanzado originalmente en <lanzamiento>2009-07-11</lanzamiento>.

</analisis>

En casos como el anterior también podemos crear un esquema que nos permita validar el archivo XML usando el atributo mixed=”true”:

<xs:element name="analisis" type="tipoanalisis"/>

<xs:complexType name="tipoanalisis" mixed="true">
    <xs:sequence>
        <xs:element name="titulo" type="xs:string"/>
        <xs:element name="desarrolladora" type="xs:string"/>
        <xs:element name="lanzamiento" type="xs:date"/>
    </xs:sequence>
</xs:complexType>

Con mixed=”true” especificamos que el elemento definido contendrá una mezcla de subelementos, atributos y texto plano. Las demás definiciones en el esquema son para validar solamente las etiquetas internas. No es necesario hacer ninguna declaración extra para el texto plano.

Indicadores

Con esquemas también puedes controlar los elementos que se utilizarán, el número de veces que lo hará, entre otras cosas. Para controlar la cantidad de veces que se repetirá un elemento puedes utilizar las sintaxis como a continuación:

<xs:element name="videojuego" type="xs:string" minOccurs="1"/> <!--límite mínimo-->

    <xs:element name="videojuego" type="xs:string" maxOccurs="500"/> <!--límite máximo-->

    <xs:element name="videojuego" type="xs:string" maxOccurs="unbounded"/> <!--para no limites-->

O puedes utilizar más de una configuración a la vez. El ejemplo siguiente nos muestra que habrá entre 1 (mínimo) y 500 (máximo) repeticiones de <videojuego>:

<xs:element name="videojuego" type="xs:string" minOccurs="1" maxOccurs="500"/>

En la entrada anterior usamos para declarar subelementos en elementos complejos y mencioné que, además de eso, también obliga a que los subelementos aparezcan en el orden en el que se declararon. Si quisiéramos que los hijos (subelementos) aparecieran en cualquier orden, siempre y cuando aparecieran solo una vez usamos <all>:

<xs:all>
    <xs:element name="titulo" type="xs:string"/>
    <xs:element name="desarrolladora" type="xs:string"/>
</xs:all>
/xml]

<p style="text-align:justify;">Si, por otro lado, quisiéramos que al menos un hijo apareciera pero nunca ambos, utilizamos <choice>:</p>

[xml]
<xs:choice>
    <xs:element name="desarrolladora" type="xs:string"/>
    <xs:element name="publicador" type="xs:string"/>
</xs:choice>

Esquemas con elementos no definidos

Si quisiéramos dar la libertad de incluir elementos no definidos en nuestro esquema, podemos utilizar el elemento <any>:

<xs:sequence>
    <xs:element name="desarrolladora" type="xs:string"/>
    <xs:element name="publicador" type="xs:string"/>
    <xs:any minOccurs=”0” maxOccurs=”2”>
</xs:sequence>

En el fragmento anterior permitimos que el documento XML contenga entre 0 y 2 elementos extra no definidos después del elemento <publicador>, cualesquiera.

Esquemas con atributos no definidos

Si, en cambio, queremos dar libertad para el uso de atributos en los elementos, utilizamos <xs:anyattribute/>:

<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:anyattribute/>
</xs:complexType>

Grupos

Los grupos en XSD son especialmente útiles cuando queremos modularizar elementos que podrían ser compartidos. Para ello se necesita la etiqueta <xs:group>.

En el siguiente ejemplo se modularizó información básica de un videojuego en grupos de modo que incluso podría ser utilizada para referirse a libros:

<xs:group name="grupodatos"> <!--Esta es la definición del grupo-->
    <xs:sequence>
        <xs:element name="titulo" type="xs:string"/>
        <xs:element name="lanzamiento" type="xs:date"/>
        <xs:element name="creador" type="xs:date"/>
   </xs:sequence>
 </xs:group>

<xs:element name="videojuego" type="infojuego"/>

<xs:complexType name="personinfo">
    <xs:sequence>
        <xs:group ref="grupodatos"/>  <!--Usamos el grupo-->
        <xs:element name="consola" type="xs:string"/>
    </xs:sequence>
</xs:complexType>

<xs:element name="libro" type="infolibro"/>

<xs:complexType name="libroinfo">
    <xs:sequence>
        <xs:group ref="grupodatos"/>  <!--Usamos el grupo-->
         <xs:element name="paginas" type="xs:integer"/>
    </xs:sequence>
</xs:complexType>

También es posible modularizar atributos para compartirlos entre elementos, de forma similar a como lo hacemos con <xs:group>, pero en este caso usando <xs:attibuteGroup>.

<xs:attributeGroup name="atributosgrupo">
    <xs:attribute name="estado" type="xs:string"/>
    <xs:attribute name="calificacionestado" type="xs:integer"/>
</xs:attributeGroup>

<xs:element name="videojuego"> <!--Definición adjunta al elemento-->
    <xs:complexType>
        <xs:attributeGroup ref="atributosgrupo"/> <!--Usamos el grupo-->
    </xs:complexType>
</xs:element>

Nota cómo en el ejemplo anterior usamos una definición de tipo complejo adjunta al elemento mismo.

Definiciones adjuntas a elementos complejos

Es posible definir elementos complejos de 2 formas distintas: adjunta al elemento o modularizada. Hasta ahora solamente habíamos utilizado la sintaxis modularizada como a continuación:

<xs:element name="videojuego" type="videoinfo"/> 

<xs:complexType name="videoinfo">
    <xs:attributeGroup ref="atributosgrupo"/>
</xs:complexType>

Las líneas anteriores también pueden ser definidas usando la siguiente sintaxis (adjunta al elemento):

<xs:element name="videojuego"> 
    <xs:complexType>
        <xs:attributeGroup ref="atributosgrupo"/>
    </xs:complexType>
</xs:element>

La única diferencia entre ambas sintaxis es que una de ellas permite modularizar las definiciones para su uso general.

Finalizando…

Espero que lo visto en esta mini serie de entradas te haya sido de utilidad. Próximamente complementaremos lo visto en ellas con temas como XQuery. Si tienes alguna duda o sugerencia, puedes dejarla en la sección de comentarios. Hasta la próxima, see ya!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *