Los atributos en
los Schemas deben definirse al final del elemento en el que se aplican, y en la
raíz del propio elemento, siguiendo la siguiente estructura:
(Modificado en los ejemplos)
<xs:element name="marca" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="nombres">
<xs:complexType>
<xs:sequence>
<xs:element name="nombre" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="idcode"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:complexType>
<xs:sequence>
<xs:element name="nombres">
<xs:complexType>
<xs:sequence>
<xs:element name="nombre" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="idcode"></xs:attribute>
</xs:complexType>
</xs:element>
Por defecto, la
aparición de los atributos no es obligatoria. Este comportamiento puede
modificarse mediante:
<xs:attribute name="idcode" use=”required”></xs:attribute>
Además, los
atributos pueden limitar el tipo de contenido. Por ejemplo, el siguiente
obligará a que sean valores numéricos:
<xs:attribute name="idcode" type=”xs:integer”></xs:attribute>
En el siguiente
caso, se podrá limitar a una serie de elementos:
<xs:attribute name="estado">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="precintado"/>
<xs:enumeration value="nuevo"/>
<xs:enumeration value="usado"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="precintado"/>
<xs:enumeration value="nuevo"/>
<xs:enumeration value="usado"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
En este otro, se
limitan los valores numéricos entre 2 rangos 18 y 30 (ambos inclusive):
<xs:attribute name="edad">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="18"/>
<xs:maxInclusive value="30"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="18"/>
<xs:maxInclusive value="30"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
O limitarlo en
base a un patrón:
<xs:attribute name="dias">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:pattern value="\d{4}\D{3}"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:pattern value="\d{4}\D{3}"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
Relaciones de dependencia
Los XML Schemas no solo nos
permiten establecer limitaciones sobre los elementos, su contenido, posición o
número. También nos permite establecer limitaciones en relación a otros
elementos del documento. Estas son las llamadas relaciones de dependencia, y muestran una gran similitud a las
bases de datos relacionales.
Por ejemplo, partimos de la
siguiente dependencia 1:N:
Donde Envío posee 3 campos:
●
scod: Código
de proveedor.
●
pcod: Código
de pieza.
●
cantidad:
Número de unidades de pieza.
En proveedor poseemos:
●
codigo:
Código de proveedor.
●
nombre:
Nombre del proveedor.
●
ciudad:
Nombre de la ciudad.
●
status:
Estado del proveedor.
En pieza tenemos:
●
codigo:
Código de la pieza.
●
nombre: Nombre
del producto.
●
Ciudad:
Dónde se fabricó.
●
Peso: En
gramos, el peso del producto.
El documento XML sería:
<?xml version="1.0" encoding="UTF-8"?>
<negocio xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="BaseDatos1.xsd">
<proveedor>
<codigo>S1</codigo>
<nombre>Juanlu</nombre>
<ciudad>granada</ciudad>
<status>100</status>
</proveedor>
<proveedor>
<codigo>S2</codigo>
<nombre>Daniel</nombre>
<ciudad>Fuengirola</ciudad>
<status>90</status>
</proveedor>
<pieza>
<codigo>P1</codigo>
<nombre>tornillo</nombre>
<ciudad>malaga</ciudad>
<peso>30</peso>
</pieza>
<pieza>
<codigo>P2</codigo>
<nombre>tuerca</nombre>
<ciudad>malaga</ciudad>
<peso>10</peso>
</pieza>
<envio scod="S1" pcod="P1" cantidad="200"/>
<envio scod="S2" pcod="P2" cantidad="100"/>
<envio scod="S2" pcod="P1" cantidad="100"/>
</negocio>
<negocio xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="BaseDatos1.xsd">
<proveedor>
<codigo>S1</codigo>
<nombre>Juanlu</nombre>
<ciudad>granada</ciudad>
<status>100</status>
</proveedor>
<proveedor>
<codigo>S2</codigo>
<nombre>Daniel</nombre>
<ciudad>Fuengirola</ciudad>
<status>90</status>
</proveedor>
<pieza>
<codigo>P1</codigo>
<nombre>tornillo</nombre>
<ciudad>malaga</ciudad>
<peso>30</peso>
</pieza>
<pieza>
<codigo>P2</codigo>
<nombre>tuerca</nombre>
<ciudad>malaga</ciudad>
<peso>10</peso>
</pieza>
<envio scod="S1" pcod="P1" cantidad="200"/>
<envio scod="S2" pcod="P2" cantidad="100"/>
<envio scod="S2" pcod="P1" cantidad="100"/>
</negocio>
En esta relación, tendremos 3
claves primarias:
●
En proveedor,
clave primaria en codigo.
●
En pieza,
clave primaria en codigo.
●
En envio,
clave primaria en scod y pcod.
Las claves primarias se definen
mediante la siguiente estructura:
<xs:key name="{nombre conjunto clave primaria}">
<xs:selector xpath="{elemento}"/>
<xs:field xpath="{elemento campo}"/>
</xs:key>
<xs:selector xpath="{elemento}"/>
<xs:field xpath="{elemento campo}"/>
</xs:key>
Por ejemplo:
<xs:key name="pkProveedor">
<xs:selector xpath="proveedor"/>
<xs:field xpath="codigo"/>
</xs:key>
<xs:selector xpath="proveedor"/>
<xs:field xpath="codigo"/>
</xs:key>
El pkProveedor será empleado más adelante para, en la clave foránea, unir este conjunto de claves primarias
con el otro conjunto de claves. El selector
permite seleccionar mediante xpath el elemento del cual se partirá en los xs:field para tomar campos para la clave
primaria. El (o los) xs:field, son
los campos que formarán parte de la clave primaria.
Lo siguiente sería una clave
foránea en la que se relaciona el atributo scod
de envio con el conjunto de claves
primarias antes definido. La forma de definirlo es:
<xs:keyref
refer="{conjunto claves primarias}" name="{nombre clave foránea}">
<xs:selector xpath="{elemento que referencia}"/>
<xs:field xpath="{campo que referencia}"/>
</xs:keyref>
<xs:selector xpath="{elemento que referencia}"/>
<xs:field xpath="{campo que referencia}"/>
</xs:keyref>
En el ejemplo:
<xs:keyref
refer="pkProveedor" name="fkProveedor">
<xs:selector xpath="envio"/>
<xs:field xpath="@scod"/>
</xs:keyref>
<xs:selector xpath="envio"/>
<xs:field xpath="@scod"/>
</xs:keyref>
Así pues,
tendríamos como conjunto de claves primarias referenciado pkProveedor, como nombre de esta relación de clave foránea fkProveedor (es obligatorio ponerle
nombre a la relación de clave foránea, aunque no se vaya a usar), y el xs:selector y xs:field funcionarán igual que en el xs:key.
El ejemplo
completo sería:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="negocio" type="tipoNegocio">
<xs:key name="pkProveedor">
<xs:selector xpath="proveedor"/>
<xs:field xpath="codigo"/>
</xs:key>
<xs:key name="pkPieza">
<xs:selector xpath="pieza"/>
<xs:field xpath="codigo"/>
</xs:key>
<xs:key name="pkEnvio">
<xs:selector xpath="envio"/>
<xs:field xpath="@scod"/>
<xs:field xpath="@pcod"/>
</xs:key>ya
<xs:keyref refer="pkProveedor" name="fkProveedor">
<xs:selector xpath="envio"/>
<xs:field xpath="@scod"/>
</xs:keyref>
<xs:keyref refer="pkPieza" name="fkPieza">
<xs:selector xpath="envio"/>
<xs:field xpath="@pcod"/>
</xs:keyref>
</xs:element>
<xs:simpleType name="codValido">
<xs:restriction base="xs:string">
<xs:pattern value="[Ss]\d{1,2}"/> <!-- "[Ss][0-9]{1,2}" -->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="cValido">
<xs:restriction base="xs:string">
<xs:pattern value="[Pp]\d{1,2}"/> <!-- "[Pp][0-9]{1,2}" -->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="v100">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="150"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="tipoNegocio">
<xs:choice maxOccurs="unbounded">
<xs:element name="proveedor" type="tipoProveedor"/>
<xs:element name="pieza" type="tipoPieza"/>
<xs:element name="envio" type="tipoEnvio"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="tipoProveedor">
<xs:sequence>
<xs:element name="codigo" type="codValido"/>
<xs:element name="nombre" type="xs:string"/>
<xs:element name="ciudad" type="xs:string"/>
<xs:element name="status" type="v100"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="tipoPieza">
<xs:sequence>
<xs:element name="codigo" type="cValido"/>
<xs:element name="nombre" type="xs:string"/>
<xs:element name="ciudad" type="xs:string"/>
<xs:element name="peso" type="v100"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="tipoEnvio">
<xs:attribute name="scod" type="xs:string"/>
<xs:attribute name="pcod" type="xs:string"/>
<xs:attribute name="cantidad" type="xs:integer"/>
</xs:complexType>
</xs:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="negocio" type="tipoNegocio">
<xs:key name="pkProveedor">
<xs:selector xpath="proveedor"/>
<xs:field xpath="codigo"/>
</xs:key>
<xs:key name="pkPieza">
<xs:selector xpath="pieza"/>
<xs:field xpath="codigo"/>
</xs:key>
<xs:key name="pkEnvio">
<xs:selector xpath="envio"/>
<xs:field xpath="@scod"/>
<xs:field xpath="@pcod"/>
</xs:key>ya
<xs:keyref refer="pkProveedor" name="fkProveedor">
<xs:selector xpath="envio"/>
<xs:field xpath="@scod"/>
</xs:keyref>
<xs:keyref refer="pkPieza" name="fkPieza">
<xs:selector xpath="envio"/>
<xs:field xpath="@pcod"/>
</xs:keyref>
</xs:element>
<xs:simpleType name="codValido">
<xs:restriction base="xs:string">
<xs:pattern value="[Ss]\d{1,2}"/> <!-- "[Ss][0-9]{1,2}" -->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="cValido">
<xs:restriction base="xs:string">
<xs:pattern value="[Pp]\d{1,2}"/> <!-- "[Pp][0-9]{1,2}" -->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="v100">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="150"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="tipoNegocio">
<xs:choice maxOccurs="unbounded">
<xs:element name="proveedor" type="tipoProveedor"/>
<xs:element name="pieza" type="tipoPieza"/>
<xs:element name="envio" type="tipoEnvio"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="tipoProveedor">
<xs:sequence>
<xs:element name="codigo" type="codValido"/>
<xs:element name="nombre" type="xs:string"/>
<xs:element name="ciudad" type="xs:string"/>
<xs:element name="status" type="v100"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="tipoPieza">
<xs:sequence>
<xs:element name="codigo" type="cValido"/>
<xs:element name="nombre" type="xs:string"/>
<xs:element name="ciudad" type="xs:string"/>
<xs:element name="peso" type="v100"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="tipoEnvio">
<xs:attribute name="scod" type="xs:string"/>
<xs:attribute name="pcod" type="xs:string"/>
<xs:attribute name="cantidad" type="xs:integer"/>
</xs:complexType>
</xs:schema>
No hay comentarios:
Publicar un comentario
¡Danos tu opinión!