Este documento es una traducción al español de la recomendación del W3C y puede encontrarse en http://www.w3c.es/Traducciones/es/TR/2001/REC-xmlschema-0-20010502/. El documento original del W3C es la única referencia oficial válida. Este documento fue finalizado el 2 de Junio de 2001. La última revisión de esta traducción se realizó el 15 de Julio de 2002.
Este documento puede contener errores de traducción, los cuales deben ser comunicados a Jose Manuel Alonso. En ocasiones aparecen aclaraciones entre corchetes y con el color de fondo de esta nota de traducción, por ejemplo, [aclaración], al lado de el vocablo o expresión original del Inglés en su primera aparición. También se han omitido de forma voluntaria algunas tildes especialmente en la traducción de elementos del código con el fin de aumentar la legibilidad.
Agradezco a César Acebal el apoyo dado durante el proceso de traducción y en general también al grupo de XJumbo por los buenos momentos.
Lo que sigue es la traducción del documento
original.
Copyright ©2001 W3C® (MIT, INRIA, Keio), Todos los Derechos Reservados. Son aplicables las reglas del W3C sobre obligaciones, marcas registradas, uso de documentos y licencias de software.
Esquema XML Parte 0: Fundamentos es un documento no-normativo hecho para proporcionar una descripción fácilmente legible de las posibilidades del Esquema XML, y está orientado a un entendimiento rápido sobre cómo crear esquemas utilizando el lenguaje Esquema XML. Esquema XML Parte 1: Estructuras y Esquema XML Parte 2: Tipos de Datos proporcionan la descripción normativa completa del lenguaje Esquema XML. Estos fundamentos describen las características del lenguaje a través de numerosos ejemplos que son complementados con referencias extensivas a los textos normativos.
Esta sección describe el estado de este documento en el momento de su publicación. Otros documentos pueden reemplazar a este documento. El último estado de esta serie de documentos se mantiene en el W3C.
Este documento ha sido revisado por miembros del W3C y otras partes interesadas y ha sido ratificada por el Director como una Recomendación del W3C. Es un documento estable y puede ser utilizado como material de referencia o citado como referencia normativa desde otro documento. El papel del W3C al hacer la Recomendación es el de atraer la atención sobre la especificación y promover su amplia difusión. Esto mejora la funcionalidad e interoperabilidad de la Web.
Este documento ha sido producido por el Grupo de Trabajo del W3C sobre el Esquema XML como parte de la Actividad XML del W3C. Las metas del lenguaje Esquema XML son discutidas en el documento de Requisitos del Esquema XML. Los autores de este documento son miembros del Grupo de Trabajo del W3C sobre el Esquema XML. Hay partes de este documento editadas por diferentes personas.
Esta versión del documento incorpora algunos cambios editoriales de versiones anteriores.
Por favor, comunique errores en este documento a www-xml-schema-comments@w3.org (archivo). La lista de errores conocidos en esta especificación está disponible en http://www.w3.org/2001/05/xmlschema-errata.
La versión Inglesa de esta especificación es la única versión normativa. La información sobre traducciones de este documento está disponible en http://www.w3.org/2001/05/xmlschema-translations.
Una lista actualizada de Recomendaciones del W3C y otros documentos técnicos puede encontrarse en http://www.w3.org/TR.
1 Introducción
2 Conceptos Básicos: Hoja de Pedido
2.1 El Esquema de la Hoja de Pedido
2.2 Definición de Tipos
Complejos, Declaración de Elementos y Atributos
2.2.1 Restricciones de Ocurrencia
2.2.2 Elementos y Atributos
Globales
2.2.3 Conflictos de Nombres
2.3 Tipos Simples
2.3.1 Tipos Lista
2.3.2 Tipos Unión
2.4 Definiciones de Tipos
Anónimos
2.5 Contenido de Elementos
2.5.1 Tipos Complejos desde
Tipos Simples
2.5.2 Contenido Mixto
2.5.3 Contenido Vacío
2.5.4 Tipo Any [Tipo Cualquiera]
2.6 Anotaciones
2.7 Construcción de Modelos de
Contenido
2.8 Grupos de Atributos
2.9 Valores Nulos
3 Conceptos Avanzados I: Espacios de Nombres,
Esquemas y Calificación
3.1 Espacios de Nombres y Locales Sin
Calificar
3.2 Locales Calificados
3.3 Declaraciones Locales contra
Globales
3.4 Espacios de Nombres Sin
Declarar
4 Conceptos Avanzados II: Hoja de Pedido
Internacional
4.1 Un Esquema en Múltiples
Documentos
4.2 Derivación de Tipos por
Extensión
4.3 Uso de Tipos Derivados en
Documentos Instancia
4.4 Derivación de Tipos
Complejos por Restricción
4.5 Redefinición de Tipos y
Grupos
4.6 Grupos de Sustitución
4.7 Elementos y Tipos Abstractos
4.8 Control de la
Creación y Uso de Tipos Derivados
5 Conceptos Avanzados III: El Informe
Trimestral
5.1 Especificar
Unicidad
5.2 Definición de Claves y
sus Referencias
5.3 Restricciones del
Esquema XML frente a Atributos ID de XML 1.0
5.4 Importación de Tipos
5.4.1 Bibliotecas de Tipos
5.5 Elemento Any [Elemento Cualquiera], Atributo Any [Atributo Cualquiera]
5.6 schemaLocation [ubicación del Esquema]
5.7 Concordancia
A Reconocimientos
B Tipos Simples y sus
Propiedades
C Uso de Entities [Uso de Entidades]
D Expresiones Regulares
E Índice
Este documento, Esquema XML Parte 0: Fundamentos, proporciona una descripción en términos sencillos a la definición del lenguaje Esquema XML, y debe ser utilizado junto con las descripciones formales del lenguaje contenidas en las Partes 1 y 2 de la especificación del Esquema XML. El público al que se dirige este documento incluye desarrolladores de aplicaciones cuyos programas leen y escriben esquemas, y autores de esquemas que necesitan conocer las características del lenguaje, especialmente las que proporcionan funcionalidad superior a la que posibilitan los DTDs. El texto asume que tienes un entendimiento básico de XML 1.0 y XML-Namespaces [Espacios de Nombres XML]. Cada una de las secciones principales de estos fundamentos introduce nuevas características del lenguaje, y describe esas características en el contexto de ejemplos concretos.
La Sección 2 cubre los mecanismos básicos del Esquema XML. Describe cómo declarar los elementos y atributos que aparecen en los documentos XML, la distinción entre tipos simples y complejos, la definición de tipos complejos, el uso de tipos simples para valores de elementos y atributos, las anotaciones del esquema, un mecanismo simple para reutilizar definiciones de elementos y atributos, y los valores nulos.
La Sección 3, la primera sección avanzada de los fundamentos, explica las bases sobre cómo son utilizados los espacios de nombres en XML y en los esquemas. Esta sección es importante para entender muchos de los temas que aparecen en las otras secciones avanzadas.
La Sección 4, la segunda sección avanzada de los fundamentos, describe mecanismos para derivar tipos de tipos existentes, y para controlar esas derivaciones. Esta sección también describe mecanismos para mezclar fragmentos de un esquema procedentes de múltiples fuentes, y para la sustitución de elementos.
La Sección 5 cubre características más avanzadas, incluyendo un mecanismo para especificar unicidad entre atributos y elementos, un mecanismo para la utilización de tipos entre distintos espacios de nombres, un mecanismo para extender tipos basados en espacios de nombres, y una descripción de cómo los documentos son validados.
Además de las secciones descritas, los fundamentos contienen un número de apéndices que proporcionan información detallada de referencia sobre tipos simples y un lenguaje de expresiones regulares.
Estos Fundamentos son un documento no-normativo, lo que significa que no proporciona una especificación definitiva del lenguaje Esquema XML (desde el punto de vista del W3C). Los ejemplos y el resto de material explicativo de este documento se proporcionan como ayuda para entender el Esquema XML, pero no siempre dan respuestas definitivas. En tales casos, necesitarás referirte a la especificación del Esquema XML, y para ayudarte en esto, te proporcionamos muchos enlaces que apuntan a las partes relevantes de la especificación. De forma más específica, los elementos del Esquema XML mencionados en el texto de los Fundamentos están enlazados a un índice de nombres de elementos y atributos, y una tabla resumen de tipos de datos, ubicadas al final de estos Fundamentos. La tabla y el índice contienen enlaces a las secciones relevantes de las partes 1 y 2 del Esquema XML.
El propósito de un esquema es definir una clase de documentos XML, y por tanto el término "documento instancia" se usa a menudo para describir un documento que conforma con un esquema en particular. De hecho, ni las instancias ni los esquemas necesitan existir como documentos per se -- pueden existir como flujos de bytes enviados entre aplicaciones, como campos en un registro de una base de datos, o como colecciones de XML Infoset "Elementos de Información" -- pero para simplificar estos fundamentos, hemos preferido referirnos a las instancias y esquemas como si fuesen documentos y ficheros.
Empecemos considerando un documento instancia en un fichero
llamado po.xml. Describe una
hoja de pedido generada por un pedido de productos para el hogar
y una aplicación de facturación:
<?xml version="1.0"?>
<hojaPedido fechaPedido="1999-10-20">
<enviarA pais="EEUU">
<nombre>Alice Smith</nombre>
<calle>123 Maple Street</calle>
<ciudad>Mill Valley</ciudad>
<estado>CA</estado>
<zip>90952</zip>
</enviarA>
<facturarA pais="EEUU">
<nombre>Robert Smith</nombre>
<calle>8 Oak Avenue</calle>
<ciudad>Old Town</ciudad>
<estado>PA</estado>
<zip>95819</zip>
</facturarA>
<comentario>¡Deprisa, mi césped parece una selva!</comentario>
<elementos>
<elemento numProducto="872-AA">
<nombreProducto>Cortacesped</nombreProducto>
<cantidad>1</cantidad>
<precioEEUU>148.95</precioEEUU>
<comentario>Confirmar que es eléctrico</comentario>
</elemento>
<elemento numProducto="926-AA">
<nombreProducto>Monitor para bebes</nombreProducto>
<cantidad>1</cantidad>
<precioEEUU>39.98</precioEEUU>
<fechaEnvio>1999-05-21</fechaEnvio>
</elemento>
</elementos>
</hojaPedido>
La hoja de pedido consiste de un elemento principal,
hojaPedido, y los subelementos enviarA,
facturarA, comentario, y
elementos. Estos subelementos (excepto
comentario) además contienen otros
subelementos, y así, hasta que un subelemento como
precioEEUU contiene un número en vez de
más subelementos. Los elementos que contienen subelementos
o tienen atributos son denominados tipos complejos, mientras que
los elementos que contienen números (y cadenas, y fechas,
etc.) pero no contienen subelementos se denominan tipos simples.
Algunos elementos tienen atributos; los atributos siempre tienen
tipos simples.
Los tipos complejos en el documento instancia, y algunos de los tipos simples, están definidos en el esquema para hojas de pedido. Los demás tipos simples están definidos como parte del repertorio de tipos simples predefinidos del Esquema XML.
Antes de continuar examinando el esquema de la hoja de pedido, nos pararemos brevemente para mencionar la asociación entre el documento instancia y el esquema de la hoja de pedido. Como puedes ver inspeccionando el documento instancia, el esquema de la hoja de pedido no es mencionado. No es necesario que una instancia se refiera a un esquema, y aunque muchas lo harán, hemos decidido mantener la simplicidad en esta primera sección, y asumir que cualquier procesador del documento instancia puede obtener el esquema de la hoja de pedido sin ninguna información adicional del documento instancia. En secciones posteriores, presentaremos mecanismos explícitos para asociar instancias y esquemas.
El esquema de la hoja de pedido está contenido en el
archivo po.xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="es">
Esquema de hoja de pedido para Example.com.
Copyright 2000 Example.com. Todos los derechos reservados.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="hojaPedido" type="TipoHojaPedido"/>
<xsd:element name="comentario" type="xsd:string"/>
<xsd:complexType name="TipoHojaPedido">
<xsd:sequence>
<xsd:element name="enviarA" type="direccionEEUU"/>
<xsd:element name="facturarA" type="direccionEEUU"/>
<xsd:element ref="comentario" minOccurs="0"/>
<xsd:element name="elementos" type="Elementos"/>
</xsd:sequence>
<xsd:attribute name="fechaPedido" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="direccionEEUU">
<xsd:sequence>
<xsd:element name="nombre" type="xsd:string"/>
<xsd:element name="calle" type="xsd:string"/>
<xsd:element name="ciudad" type="xsd:string"/>
<xsd:element name="estado" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="pais" type="xsd:NMTOKEN" fixed="EEUU"/>
</xsd:complexType>
<xsd:complexType name="Elementos">
<xsd:sequence>
<xsd:element name="elemento" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nombreProducto" type="xsd:string"/>
<xsd:element name="cantidad">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="precioEEUU" type="xsd:decimal"/>
<xsd:element ref="comentario" minOccurs="0"/>
<xsd:element name="fechaEnvio" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="numProducto" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit [Código de Almacenaje], -->
<!-- un código para identificar productos -->
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
El esquema de la hoja de pedido consiste de un elemento
schema y una variedad
de subelementos, los más notables, element[elemento], complexType[tipo complejo], y simpleType [tipo simple] que determinan la
aparición de elementos y su contenido en documentos
instancia.
Cada uno de los elementos del esquema tiene
el prefijo xsd: que está asociado con el
espacio de nombres del Esquema XML a través de la
declaración,
xmlns:xsd="http://www.w3.org/2001/XMLSchema", que
aparece en el elemento schema. El prefijo xsd:
es usado por convención para denotar el espacio de nombres
del Esquema XML, aunque puede utilizarse cualquier prefijo. El
mismo prefijo, y por tanto la misma asociación,
también aparece en los nombres de los tipos simples
predefinidos, por ejemplo xsd:string. El propósito de la
asociación es identificar los elementos y tipos simples
como pertenecientes al vocabulario del lenguaje Esquema XML y no
al vocabulario del autor del esquema. Por consideración a
la claridad en el texto, sólo mencionamos los nombres de
elementos y tipos simples (p.e. simpleType), y omitimos el
prefijo.
En el Esquema XML, existe una diferencia básica entre los tipos complejos que permiten elementos en su contenido y que pueden tener atributos, y los tipos simples que no pueden tener contenido de elementos ni pueden tener atributos.
También existe una gran distinción entre definiciones que crean tipos nuevos (ya sean simples o complejos), y declaraciones que posibilitan que elementos y atributos con nombre y tipos específicos (ya sean simples o complejos) aparezcan en documentos instancia. En esta sección, nos centramos en la definición de tipos complejos y los elementos y atributos que aparecen en ellos.
Los tipos complejos nuevos se definen
utilizando el elemento complexType y tales
definiciones contienen típicamente un conjunto de
declaraciones de elementos, referencias a elementos, y
declaraciones de atributos. Las declaraciones no son tipos en
sí mismas, si no más bien una asociación
entre un nombre y unas restricciones que dirigen la apariencia de
ese nombre en documentos gobernados por el esquema asociado. Los
elementos se declaran utilizando el elemento element, y los atributos se
declaran utilizando el elemento attribute. Por ejemplo,
direccionEEUU está definido como un tipo
complejo, y dentro de la definición de
direccionEEUU vemos cinco declaraciones de elementos
y una declaración de atributo:
<xsd:complexType name="direccionEEUU"> <xsd:sequence> <xsd:element name="nombre" type="xsd:string"/> <xsd:element name="calle" type="xsd:string"/> <xsd:element name="ciudad" type="xsd:string"/> <xsd:element name="estado" type="xsd:string"/> <xsd:element name="zip" type="xsd:decimal"/> </xsd:sequence> <xsd:attribute name="pais" type="xsd:NMTOKEN" fixed="EEUU"/> </xsd:complexType>
La consecuencia de esta definición
es que cualquier elemento que aparezca en la instancia cuyo tipo
sea direccionEEUU (p.e. enviarA en
po.xml) debe consistir de
cinco elementos y un atributo. Estos elementos deben denominarse
nombre, calle, ciudad,
estado y zip como se especifica
según los valores de los atributos name en
sus declaraciones, y los elementos deben aparecen en la misma
secuencia (orden) en la que son declarados. Los cuatro primeros
elementos contendrán una cadena de caracteres cada uno, y
el quinto contendrá un número. El elemento cuyo
tipo ha sido declarado como direccionEEUU puede
aparecer con un atributo llamado pais que debe
contener la cadena EEUU.
La definición de
direccionEEUU contiene declaraciones que solamente
son de los tipos simples: string, decimal y NMTOKEN. Por contra, la definición
de TipoHojaPedido contiene declaraciones de
elementos que son de tipos complejos, p.e.
direccionEEUU, aunque hay que resaltar que ambas
declaraciones hacen uso del mismo atributo type para identificar el tipo, sin
importar que el tipo sea simple o complejo.
<xsd:complexType name="TipoHojaPedido"> <xsd:sequence> <xsd:element name="enviarA" type="direccionEEUU"/> <xsd:element name="facturarA" type="direccionEEUU"/> <xsd:element ref="comentario" minOccurs="0"/> <xsd:element name="elementos" type="Elementos"/> </xsd:sequence> <xsd:attribute name="fechaPedido" type="xsd:date"/> </xsd:complexType>
Al definir TipoHojaPedido, dos de las
declaraciones de elementos, las de enviarA y
facturarA, asocian elementos diferentes con el mismo
tipo complejo, llamado direccionEEUU. La
consecuencia de esta definición es que cualquier elemento
que aparezca en un documento instancia (p.e. po.xml) cuyo tipo sea
TipoHojaPedido, debe tener elementos llamados
enviarA y facturarA, y cada uno de
ellos debe contener los cinco subelementos (nombre,
calle, ciudad, estado y
zip ) que fueron declarados como parte de
direccionEEUU. Los elementos enviarA y
facturarA deben tener también el atributo
pais que fue declarado como parte de
direccionEEUU.
La definición de TipoHojaPedido contiene
una declaración de atributo fechaPedido que,
como la declaración del atributo pais, es de
un tipo simple. De hecho, todas las declaraciones de atributos
deben referenciar a tipos simples porque, a diferencia de las
declaraciones de elementos, los atributos no pueden contener
otros elementos o atributos.
Cada una de las declaraciones de elementos que hemos descrito hasta ahora tiene asociado el nombre de un tipo definido. A veces es preferible utilizar un elemento existente en vez de declarar un elemento nuevo, por ejemplo:
<xsd:element ref="comentario" minOccurs="0"/>
Esta declaración hace referencia a un tipo existente,
comentario, que fue declarado en alguna otra parte
del esquema de la hoja de pedido. En general, el valor del
atributo ref debe hacer
referencia a un elemento global, es decir, uno que ha sido
declarado bajo el schema y no como parte de una
declaración de un tipo complejo. La consecuencia de esta
declaración es que un elemento denominado
comentario puede aparece en un documento instancia,
y su contenido debe ser coherente con el tipo de ese elemento, en
este caso, string.
El elemento comentario es
opcional dentro de TipoHojaPedido porque el valor
del atributo minOccurs en su
declaración es igual a 0. En general, se requiere la
aparición de un elemento cuando el valor de minOccurs es 1 ó mayor.
El número máximo de veces que puede aparecer un
elemento es determinado por el valor del atributo maxOccurs en su
declaración. Este valor puede ser un entero positivo como
41, o el término unbounded [sin límite] para indicar que no
existe un número máximo de ocurrencias. El valor
por defecto de ambos atributos, el minOccurs y el maxOccurs es 1. Así,
cuando un elemento como comentario es declarado sin
un atributo maxOccurs, el elemento no puede
aparecer más de una vez. Asegúrate de que si
sólo especificas un valor para el atributo minOccurs, es menor o igual que
el valor por defecto del atributo maxOccurs, es decir, es 0
ó 1. De forma similar, si sólo especificas un valor
para el atributo maxOccurs, debe ser mayor o
igual que el valor por defecto de minOccurs, es decir, 1 o mayor.
Si ambos atributos son omitidos, el elemento debe aparecer
exactamente una vez.
Los atributos pueden aparecer una vez o
ninguna, pero ningún otro número de veces, por eso
la sintaxis para especificar ocurrencias de atributos es
diferente que la sintaxis para elementos. En particular, los
atributos pueden ser declarados con un atributo use para indicar si el atributo es
required [requerido]
(ver por ejemplo, la declaración del atributo
numProducto en po.xsd), optional [opcional], o incluso prohibited
[prohibido].
Los valores por defecto de elementos y atributos son
declarados utilizando el atributo default[defecto], aunque este atributo tiene
una consecuencia diferente en cada caso. Cuando un atributo es
declarado con un valor por defecto, el valor del atributo es
aquel que aparece en como valor del atributo en un documento
instancia, si el atributo no aparece en el documento instancia,
el procesador del esquema iguala el atributo al valor del
atributo default. Hay que resaltar
que los valores por defecto de los atributos, sólo tienen
sentido si los propios atributos son opcionales, por lo que es un
error especificar a la vez un valor por defecto y cualquier valor
distinto de optional para use.
El procesador de esquemas trata a los elementos por defecto de
forma un poco diferente. Cuando un elemento es declarado con un
valor por defecto, el valor del elemento es cualquier valor que
aparece como contenido del elemento en un documento instancia, si
el elemento aparece sin contenido, el procesador de esquemas
iguala el elemento al valor del atributo default. De todas formas, si
el elemento no aparece en el documento instancia, el procesador
de esquemas no da ningún valor al elemento. En resumen, la
diferencia de tratamiento entre atributos y elementos por defecto
es: las valores por defecto de los atributos se aplican cuando
éstos no están presentes, y los valores por defecto
de los elementos se aplican cuando éstos están
vacíos.
El atributo fixed [fijo] se utiliza en declaraciones de
elementos y atributos para asegurar que los elementos y atributos
son igualados a valores particulares. Por ejemplo, po.xsd contiene una declaración para
el atributo pais, que se declara con valor fixed igual a
EEUU. Esta declaración significa que la
aparición de un atributo pais en un documento
instancia es opcional (el valor por defecto de use es optional), aunque
si el atributo aparece, su valor debe ser EEUU. Hay
que resaltar que los conceptos de un valor fijo y de un valor por
defecto son mutuamente excluyentes, y por tanto es un error para
una declaración contener ambos atributos
fixed y default.
Los valores de los atributos utilizados en declaraciones de elementos y atributos para restringir sus ocurrencias se resumen en la Tabla 1.
| Tabla 1. Restricciones de Ocurrencia para Elementos y Atributos | ||
|---|---|---|
| Elementos (minOccurs, maxOccurs) fixed, default |
Atributos use, fixed, default |
Notas |
| (1, 1) -, - | required, -, - | el elemento/atributo debe aparece una vez, puede tener cualquier valor |
| (1, 1) 37, - | required, 37, - | el elemento/atributo debe aparecer una vez, su valor debe ser 37 |
| (2, unbounded) 37, - | n/a | el elemento debe aparecer dos veces o más, su valor debe ser 37; en general, los valores de minOccurs y maxOccurs deben ser enteros positivos, y el de maxOccurs también puede ser "unbounded" |
| (0, 1) -, - | optional, -, - | el elemento/atributo puede aparecer una vez, puede tener cualquier valor |
| (0, 1) 37, - | optional, 37, - | el elemento/atributo puede aparecer una vez, si aparece su valor debe ser 37, si no aparece su valor es 37 |
| (0, 1) -, 37 | optional, -, 37 | el elemento/atributo puede aparecer una vez; si no aparece su valor es 37, en otro caso su valor es el dado |
| (0, 2) -, 37 | n/a | el elemento puede aparecer una vez, dos, o ninguna; si el elemento no aparece no es aplicable; si aparece y es vacío su valor es 37; en otro caso es el valor dado; en general, los valores de minOccurs y maxOccurs deben ser enteros positivos, y el de maxOccurs también puede ser "unbounded" |
| (0, 0) -, - | prohibited, -, - | el elemento/atributo no debe aparecer |
| Nótese que ni minOccurs, maxOccurs, ni use pueden aparecer en las declaraciones de elementos y atributos globales. | ||
Los elementos y atributos globales, son creados por
declaraciones que aparecen como hijos del elemento schema. Una vez declarado, un
elemento o atributo global puede ser referenciado en una o
más declaraciones utilizando el atributo ref según se ha descrito
arriba. Una declaración que hace referencia a un elemento
global posibilita que el elemento aparezca en el documento
instancia en el contexto de la declaración referente.
Así, por ejemplo el elemento comentario
aparece en po.xml al mismo
nivel que los elementos enviarA,
facturarA y elementos porque la
declaración que referencia a comentario
aparece en la definición del tipo complejo al mismo nivel
que las declaraciones de los otros tres elementos.
La declaración de un elemento global también
posibilita que el elemento aparezca en el nivel raíz de un
documento instancia. Así, hojaPedido, que es
declarado como un elemento global en po.xsd, puede aparecer como el elemento
raíz en po.xml. Hay que
hacer notar que este razonamiento también permitirá
a un elemento comentario aparecer como el elemento
raíz en un documento como po.xml.
Hay un número de advertencias que atañen al uso
de elementos y atributos globales. Una advertencia es que las
declaraciones globales no pueden contener referencias; las
declaraciones globales deben identificar tipos simples y
complejos directamente. En concreto, las declaraciones globales
no pueden contener el atributo ref, deben utilizar el atributo
type (o, como
describiremos en breve, estar seguidas de una definición de tipo anónimo).
Una segunda advertencia es que las restricciones de cardinalidad
no pueden ser colocadas en declaraciones globales, aunque pueden
ser colocadas en declaraciones locales que referencien a
declaraciones globales. En otras palabras, las declaraciones
globales no pueden contener los atributos minOccurs, maxOccurs, o use.
Hemos descrito como definir tipos complejos (p.e.
TipoHojaPedido), declarar elementos (p.e.
hojaPedido) y declarar atributos (p.e.
fechaPedido) . Estas actividades generalmente
incluyen la asignación de nombres, y así surge la
siguiente pregunta: ¿Qué ocurre si le damos el
mismo nombre a dos cosas diferentes? La respuesta depende de las
dos cosas en cuestión, aunque en general, cuanto
más parecidas son ambas cosas, más probabilidades
de que exista un conflicto.
He aquí algunos ejemplos para ilustrar cuando los nombres iguales causan problemas. Si las dos cosas son tipos, digamos que definimos un tipo complejo llamado EstadoEEUU y un tipo simple llamado EstadoEEUU, existe un conflicto. Si las dos cosas son un tipo y un elemento o atributo, digamos que definimos un tipo complejo llamado DireccionEEUU y que declaramos un elemento llamado DireccionEEUU, no existe conflicto. Si las dos cosas son elementos dentro de tipos diferentes, (es decir, no son elementos globales), digamos que declaramos un elemento llamado nombre como parte del tipo DireccionEEUU y un segundo elemento llamado nombre como parte del tipo Elementos, no existe conflicto. (Tales elementos son a menudo denominados declaraciones de elementos locales). Finalmente, si las dos cosas son tipos y tú defines una y el Esquema XML ha definido la otra, digamos que tú has definido un tipo simple llamado decimal, no existe conflicto. La razón de esta contradicción aparente en el último ejemplo es que los dos tipos pertenecen a espacios de nombres distintos. Exploraremos el uso de espacios de nombre en los esquemas en una sección posterior.
El esquema de la hoja de pedido declara varios elementos y
atributos que tienen tipos simples. Algunos de estos tipos
simples como string y decimal, están predefinidos en
el Esquema XML, mientras que otros son derivados de los
predefinidos. Por ejemplo el atributo numProducto
tiene un tipo llamado SKU (Stock Keeping Unit [Código de Almacenaje]) que se
deriva de string. Tanto los
tipos simples como sus derivaciones pueden ser utilizados en
todas las declaraciones de elementos y atributos. La Tabla 2 lista todos los atributos simples
predefinidos en el Esquema XML, junto con ejemplos de los
diferentes tipos.
| Tabla 2. Tipos Simples Predefinidos en el Esquema XML | ||
|---|---|---|
| Tipo Simple | Ejemplos (delimitados por comas) | Notas |
| string | Confirmar que es eléctrico | |
| normalizedString | Confirmar que es eléctrico | ver (3) |
| token | Confirmar que es eléctrico | ver (4) |
| byte | -1, 126 | ver (2) |
| unsignedByte | 0, 126 | ver (2) |
| base64Binary | GpM7 | |
| hexBinary | 0FB7 | |
| integer | -126789, -1, 0, 1, 126789 | ver (2) |
| positiveInteger | 1, 126789 | ver (2) |
| negativeInteger | -126789, -1 | ver (2) |
| nonNegativeInteger | 0, 1, 126789 | ver (2) |
| nonPositiveInteger | -126789, -1, 0 | ver (2) |
| int | -1, 126789675 | ver (2) |
| unsignedInt | 0, 1267896754 | ver (2) |
| long | -1, 12678967543233 | ver (2) |
| unsignedLong | 0, 12678967543233 | ver (2) |
| short | -1, 12678 | ver (2) |
| unsignedShort | 0, 12678 | ver (2) |
| decimal | -1.23, 0, 123.4, 1000.00 | ver (2) |
| float | -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN | equivalente a punto flotante de precisión simple de 32-bit, NaN es "not a number" ["no es un número"], ver (2) |
| double | -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN | equivalente a punto flotante de doble precisión 64-bit, ver (2) |
| boolean | true, false 1, 0 |
[verdadero, falso] |
| time | 13:20:00.000, 13:20:00.000-05:00 | ver (2) |
| dateTime | 1999-05-31T13:20:00.000-05:00 | 31 de Mayo de 1999 a las 1.20pm Hora Estándar de la Costa Este que va 5 horas por detrás de la Hora Universal, ver (2) |
| duration | P1Y2M3DT10H30M12.3S | 1 año, 2 meses, 3 días, 10 horas, 30 minutos, 2 meses, 3 días, 10 horas, 30 minutos, y 12.3 segundos |
| date | 1999-05-31 | ver (2) |
| gMonth | --05-- | Mayo, ver (2) (5) |
| gYear | 1999 | 1999, ver (2) (5) |
| gYearMonth | 1999-02 | el mes de Febrero de 1999, sin importar el número de días, ver (2) (5) |
| gDay | ---31 | el día 31, ver (2) (5) |
| gMonthDay | --05-31 | cada 31 de Mayo, ver (2) (5) |
| Name | enviarA | tipo Nombre de XML 1.0 |
| QName | po:direccionEEUU | QName de Espacio de Nombres XML |
| NCName | direccionEEUU | NCName del Espacio de Nombres XML, p.e. un QName sin el prefijo ni los dos puntos |
| anyURI | http://www.example.com/, http://www.example.com/doc.html#ID5 | |
| language | en-GB, en-US, fr | valores válidos para xml:lang según está definido en XML 1.0 |
| ID | atributo tipo ID XML 1.0, ver (1) | |
| IDREF | atributo tipo IDREF XML 1.0, ver (1) | |
| IDREFS | atributo tipo IDREFS XML 1.0, ver (1) | |
| ENTITY | atributo tipo ENTITY XML 1.0, ver (1) | |
| ENTITIES | atributo tipo ENTITIES XML 1.0, ver (1) | |
| NOTATION | atributo tipo NOTATION XML 1.0, ver (1) | |
| NMTOKEN | US, Brasil |
atributo tipo NMTOKEN XML 1.0, ver (1) |
| NMTOKENS | US UK, Brasil Canada Mexico |
atributo tipo NMTOKENS XML 1.0, p.e. una lista de NMTOKENs separada por espacios en blanco, ver (1) |
|
Notas: (1) Para mantener la compatibilidad entre el Esquema XML y los DTD de XML 1.0, los tipos simples ID, IDREF, IDREFS, ENTITY, ENTITIES, NOTATION, NMTOKEN, NMTOKENS deberían ser usados sólo en atributos. (2) Un valor de este tipo puede ser representado por más de un forma léxica, p.e. 100 y 1.0E2 son ambos formatos válidos flotantes que representan "un ciento". De todas formas, han sido establecidas reglas para este tipo que definen una forma léxica canónica, ver el Esquema XML Parte 2. (3) Los caracteres nueva línea, tabulador y retorno de carro en un tipo normalizedString son convertidos a caracteres de espacio en blanco antes del procesamiento del esquema. (4) Como en normalizedString, los espacios en blanco adyacentes son comprimidos a un sólo espacio en blanco, y los espacios en blanco de delante y detrás son eliminados. (5) El prefijo "g" señala periodos de tiempo en el calendario Gregoriano. |
||
Los tipos simples nuevos se definen
derivándolos de los tipos simples existentes (los
predefinidos y derivados). En particular, podemos derivar un tipo
simple nuevo restringiendo un tipo simple existente, en otras
palabras, el rango legal es un subconjunto del rango de valores
existente del tipo. Se utiliza el elemento simpleType [tipoSimple] para definir y nombrar el tipo
simple nuevo. Se utiliza el elemento restriction [restricción] para indicar el tipo
(base) existente y para identificar las "propiedades" que
restringen el rango de valores. Se proporciona una lista de
propiedades completa en el Apéndice B.
Supongamos que queremos crear un tipo nuevo
de entero miEntero llamado cuyo rango de valores
esté entre 10000 y 99999 (inclusive). Basamos nuestra
definición en el tipo predefinido integer [entero], cuyo rango de valores
también incluye enteros menores que 10000 y mayores que
99999. Para definir miEntero, restringimos el rango
del tipo base integer
empleando dos propiedades denominadas minInclusive y maxInclusive:
<xsd:simpleType name="miEntero">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>
El ejemplo muestra una combinación particular de un
tipo base de dos propiedades utilizadas para definir
miEntero, pero un vistazo a la lista de tipos y
propiedades predefinidas (Apéndice B) podría sugerir
otras posibles combinaciones.
El esquema de la hoja de pedido contiene
otro ejemplo, más elaborado, de una definición de
tipo simple. Un tipo simple nuevo llamado SKU se
deriva (por restricción) del tipo simple string [cadena]. Más aún, restringimos
los valores de SKU utilizando una propiedad llamada
pattern [patrón] en conjunción con la
expresión regular "\d{3}-[A-Z]{2}" que se lee
como "tres dígitos seguidos de un guión seguido de
dos caracteres ASCII en mayúsculas":
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
Este lenguaje de expresiones regulares se describe en mayor profundidad en el Apéndice D.
El Esquema XML define quince propiedades
que están listadas en el Apéndice B. Entre ellas, la
propiedad enumeration [enumeración] es particularmente
útil y pude ser usada para restringir los valores de casi
todos los tipos simples, excepto el boolean [booleano]. La propiedad enumeration limita un tipo
simple a un conjunto de valores distintos. Por ejemplo, podemos
usar la propiedad enumeration para definir un
tipo simple nuevo llamado estadoEEUU, derivado de
string, cuyo valor debe ser
una de las abreviaciones estándar de estado de EEUU:
<xsd:simpleType name="estadoEEUU">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="AK"/>
<xsd:enumeration value="AL"/>
<xsd:enumeration value="AR"/>
<!-- y así el resto ... -->
</xsd:restriction>
</xsd:simpleType>
estadoEEUU, sería un buen sustituto para
el tipo string utilizado
actualmente en la declaración del elemento
estado. Haciendo esta sustitución, los
valores legales de un elemento estado, es decir, los
subelementos estado de facturarA y
enviarA, estarían limitados a alguno de
AK, AL, AR, etc.
Nótese que los valores especificados para un tipo
particular deben ser únicos.
El Esquema XML tiene el concepto de tipo lista, además
de los llamados tipos atómicos que son la mayoría
de los tipos listados en la Tabla
2. (Los tipos atómicos, tipos lista, y los tipos
unión descritos en la próxima sección son
llamados colectivamente tipos simples). El valor de un tipo
atómico es indivisible desde la perspectiva del Esquema
XML. Por ejemplo, el NMTOKEN
de valor EEUU
es indivisible en el sentido en que ninguna parte de
EEUU, como el carácter "U", tiene
ningún significado por si misma. Por contra, los tipos
lista están compuestos de secuencias de tipos
atómicos y consecuentemente las partes de una secuencia
(los "átomos") tienen sentido. Por ejemplo, NMTOKENS es un tipo lista, y un elemento
de ese tipo sería una lista de NMTOKEN's delimitados por espacio en
blanco, tales como "EEUU UK FR" . El Esquema XML tiene tres tipos
de lista predefinidos, son NMTOKENS, IDREFS, y ENTITIES.
Además de utilizar los tipos de
lista predefinidos, puedes crear nuevos tipos de listas por
derivación de los tipos atómicos existentes. (No
puedes crear tipos de lista partiendo de tipos de lista
existentes, ni de tipos complejos). Por ejemplo, para crear una
lista de elementos miEntero:
<xsd:simpleType name="listaDeMisEnteros"> <xsd:list itemType="miEntero"/> </xsd:simpleType>
Y un elemento en un documento instancia cuyo contenido
conforme con el de listaDeMisEnteros es:
<listaDeMisEnteros>20003 15037 95977 95945</listaDeMisEnteros>
Pueden aplicarse varias propiedades a los
tipos lista: length
[longitud], minLength [longitud mínima], maxLength [longitud máxima], y enumeration [enumeración]. Por ejemplo, para
definir una lista de seis estados exactamente
(SeisEstadosEEUU), definimos primero un tipo de
lista nuevo llamado ListaEstadosEEUU a partir de
EstadoEEUU), y entonces derivamos
SeisEstadosEEUU, restringiendo
ListaEstadosEEUU a sólo seis elementos:
<xsd:simpleType name="ListaEstadosEEUU"> <xsd:list itemType="estadoEEUU"/> </xsd:simpleType> <xsd:simpleType name="SeisEstadosEEUU"> <xsd:restriction base="ListaEstadosEEUU"> <xsd:length value="6"/> </xsd:restriction> </xsd:simpleType>
Los elementos cuyo tipo sea SeisEstadosEEUU deben
tener seis elementos, y cada uno de los seis elementos, debe ser
uno de los valores (atómicos) del tipo enumerado
EstadoEEUU, por ejemplo:
<seisEstados>PA NY CA NY LA AK</seisEstados>
Resaltemos que es posible derivar un tipo lista del tipo
atómico string [cadena de caracteres]. Sin embargo, un
string puede contener espacios
en blanco, y los espacios en blanco delimitan los elementos de
una lista, por lo que deberías tener cuidado al definir
tipos lista cuyo tipo base sea el string. Por ejemplo, supón que hemos
definido un tipo lista cuya propiedad length es igual a 3, y de tipos base
string, entonces la siguiente
lista de tres elementos es legal:
Asia Europa Africa
Pero la siguiente lista de tres elementos no es legal:
Asia Europa America Latina
Incluso aunque "America Latina" puede existir como una cadena de caracteres simple fuera de la lista, cuando se incluye en la lista, el espacio en blanco entre America y Latina crea un cuarto elemento, y por eso el último ejemplo no conformará con el tipo lista de 3 elementos.
Los tipos atómicos y los tipos
lista posibilitan el que el valor de un elemento o atributo sea
de una o más instancias de un tipo atómico. Por
contra, un tipo unión facilita el que el valor de un
elemento o atributo sea de una o más instancias de un tipo
formado por la unión de múltiples tipos
atómicos y tipos lista. Para ilustrar esto, creemos un
tipo unión para representar los estados Americanos como
abreviaciones de letras únicas o listas de códigos
numéricos. El tipo unionZips se forma a
partir de un tipo atómico y un tipo lista:
<xsd:simpleType name="unionZips">
<xsd:union memberTypes="estadoEEUU listaDeMisEnteros"/>
</xsd:simpleType>
Cuando definimos un tipo unión, el atributo
memberTypes [tiposMiembro] es una lista de todos los
tipos de la unión.
Ahora, asumiendo que hemos declarado un elemento llamado
zips de tipo unionZips, instancias
válidas del elemento son:
<zips>CA</zips> <zips>95630 95977 95945</zips> <zips>AK</zips>
Dos propiedades, pattern y enumeration, pueden ser
aplicadas a un tipo unión.
Los Esquemas pueden ser construidos definiendo conjuntos de
tipos con nombre tales como TipoHojaPedido y
entonces declarando elementos como hojaPedido que
referencian a los tipos usando la construcción type= . Este estilo de
construcción del esquema es directo pero puede ser
engorroso, especialmente si se definen muchos tipos que son
referenciados una sola vez y contienen muy pocas restricciones.
En estos casos, un tipo puede ser definido de forma más
breve como un tipo anónimo, lo que evita la sobrecarga de
tener que nombrarlo y referenciarlo explícitamente.
La definición del tipo Elementos en
po.xsd contiene declaraciones
de dos elementos que utilizan tipos anónimos
(elemento y cantidad). En general,
puedes identificar tipos anónimos por la falta de un
type= en una
declaración de elemento (o atributo), y por la presencia
de una declaración de tipo con nombre (simple o
compleja):
<xsd:complexType name="Elementos">
<xsd:sequence>
<xsd:element name="elemento" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nombreProducto" type="xsd:string"/>
<xsd:element name="cantidad">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="precioEEUU" type="xsd:decimal"/>
<xsd:element ref="comentario" minOccurs="0"/>
<xsd:element name="fechaEnvio" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="numProducto" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
En el caso del elemento elemento, tiene un tipo
anónimo complejo formado por los elementos
nombreProducto, cantidad,
precioEEUU, comentario, y
fechaEnvio, y un atributo llamado
numProducto. En el caso del elemento
cantidad, tiene un tipo anónimo simple
derivado de integer cuyo
valor está comprendido entre 1 y 99.
El esquema de la hoja de pedido tiene muchos ejemplos de
elementos que contiene otros elementos (p.e.
elementos), elementos con atributos que contienen
otros elementos (p.e. enviarA), y elementos que
contienen sólo un valor de tipo simple (p.e.
precioEEUU). De todas formas, no hemos visto
ningún elemento que contenga atributos pero que contenga
sólo un valor de tipo simple, ni tampoco hemos visto un
elemento que contenga otros elementos mezclados con contenido de
caracteres, ni hemos visto elementos sin contenido. En esta
sección examinaremos estas variaciones en el contenido de
los modelos de elementos.
Permítenos considerar primero cómo declarar un elemento que tiene un atributo y contiene un valor simple. En un documento instancia, tal elemento debería aparecer como:
<precioInternacional moneda="EUR">423.46</precioInternacional>
El esquema de la hoja de pedido declara un elemento
precioEEUU que es el punto de partida:
<xsd:element name="precioEEUU" type="decimal"/>
Pero, ¿cómo añadimos
un atributo a este elemento? Como hemos dicho antes, los tipos
simples no pueden tener atributos, y decimal es un tipo simple. Por tanto,
debemos definir un tipo complejo que lleve la declaración
del atributo. También queremos que el contenido sea del
tipo simple decimal.
Así que nuestra pregunta original se convierte en
¿cómo definimos un tipo complejo basado en el tipo
simple decimal? La respuesta
es derivar un tipo complejo nuevo del tipo simple
decimal:
<xsd:element name="precioInternacional">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:decimal">
<xsd:attribute name="moneda" type="xsd:string"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
Utilizamos el elemento complexType para comenzar la
definición de un nuevo tipo (anónimo). Para indicar
que el modelo de contenido del nuevo tipo contiene sólo
caracteres y no elementos, utilizamos un elemento simpleContent. Finalmente,
derivamos el nuevo tipo extendiendo el tipo simple decimal. La extensión consiste en
añadir un atributo moneda utilizando una
declaración estándar de atributo. (Hablaremos de la
derivación de tipos en detalle en la Sección 4). El elemento
precioInternacional declarado de esta manera
aparecerá en una instancia como se muestra en el ejemplo
al principio de esta sección.
La construcción del esquema de la hoja de pedido puede caracterizarse por elementos que contienen subelementos, y los elementos del nivel más profundo contienen caracteres de datos. El Esquema XML también posibilita la construcción de esquemas en los que los caracteres pueden aparecer junto con los subelementos, y los caracteres no están confinados al más profundo de los niveles.
Para ilustrar esto, considera el siguiente fragmento de una carta de un cliente que utiliza elementos de la hoja de pedido:
<cuerpoCarta> <saludo>Querido Sr.<nombre>Robert Smith</nombre>.</saludo> Su pedido de <cantidad>1</cantidad> <nombreProducto> Monitor de Bebés</nombreProducto> fue enviado desde nuestro almacén el <fechaEnvio>1999-05-21</fechaEnvio>. .... </cuerpoCarta>
Nótese que el texto aparece entre los elementos y sus
elementos hijo. Específicamente, el texto aparece entre
los elementos saludo, cantidad,
nombreProducto y fechaEnvio que son
todos hijos de cuerpoCarta, y el texto aparece
alrededor del elemento nombre que es el hijo de un hijo de
cuerpoCarta. El siguiente fragmento de un esquema
declara cuerpoCarta:
<xsd:element name="cuerpoCarta">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="saludo">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="nombre" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="cantidad" type="xsd:positiveInteger"/>
<xsd:element name="nombreProducto" type="xsd:string"/>
<xsd:element name="fechaEnvio" type="xsd:date" minOccurs="0"/>
<!-- etc. -->
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Los elementos que aparecen en la carta del cliente se
declaran, y sus tipos se definen utilizando las construcciones de
element y complexType que hemos
visto anteriormente. Para que sea posible el que aparezcan
caracteres entre los elementos hijo de cuerpoCarta,
el atributo mixed en
la definición del tipo se ha puesto a true [verdadero].
Nótese que el modelo en el Esquema XML difiere
fundamentalmente del modelo
mixed en XML 1.0. En el modelo mixto de Esquema
XML, el orden y número de los elementos hijo que aparecen
en una instancia debe coincidir en tipo y número con los
elementos hijo especificados en el modelo. Por contra, en el
modelo mixto de XML 1.0, el orden y número de los
elementos hijo de la instancia no puede ser restringido. En
resumen, el Esquema XML proporciona validación total de
modelos mixtos en contraste con la validación parcial
proporcionada por el XML 1.0.
Supongamos que queremos que el elemento
precioInternacional contenga la unidad de moneda y
el precio como valores de atributos en vez de tenerlos como
valores separados de atributo y contenido. Por ejemplo:
<precioInternacional moneda="EUR" valor="423.46"/>
Tal elemento no tiene ningún contenido; su modelo de contenido es vacío. Para definir un elemento de contenido vacío, esencialmente definimos un tipo que sólo permite elementos en su contenido, pero realmente no declaramos ningún elemento y así conseguimos que su modelo de contenido sea vacío:
<xsd:element name="precioInternacional">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:attribute name="moneda" type="xsd:string"/>
<xsd:attribute name="valor" type="xsd:decimal"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
En este ejemplo, definimos un tipo (anónimo) que tiene
complexContent, es decir, sólo elementos. El
elemento complexContent indica que tenemos que
restringir o extender el modelo de contenido de un tipo complejo,
y la restriction de anyType [cualquierTipo] declara dos atributos
pero no presenta ningún contenido para el elemento (ver Sección 4.4 para más
detalles sobre restricción). El elemento
precioInternacional declarado de esta forma puede
aparecer legítimamente en una instancia como se muestra en
el ejemplo anterior.
La sintaxis anterior para un elemento de contenido
vacío es relativamente prolija, y es posible declarar el
elemento precioInternacional de manera más
compacta:
<xsd:element name="precioInternacional"> <xsd:complexType> <xsd:attribute name="moneda" type="xsd:string"/> <xsd:attribute name="valor" type="xsd:decimal"/> </xsd:complexType> </xsd:element>
Esta sintaxis compacta funciona porque un tipo complejo
definido sin ningún simpleContent o
complexContent es interpretado como una forma
abreviada para contenido complejo que restringe
anyType.
El anyType representa una abstracción
llamada el
ur-type que es el tipo base del que derivan todos los
tipos simples y complejos. Un tipo anyType no
restringe su contenido en modo alguno. Es posible utilizar
anyType como otros tipos, por ejemplo:
<xsd:element name="cualquiercosa" type="xsd:anyType"/>
El contenido del elemento declarado de esta manera no
está restringido, así que el elemento puede valer
423.46, pero también puede ser cualquier otra secuencia de
caracteres, o una mezcla de caracteres y elementos. De hecho,
anyType es el tipo por defecto cuando no se
especifica ninguno, así que el ejemplo anterior puede
escribirse también como:
<xsd:element name="cualquiercosa"/>
Si se necesita contenido de elementos sin restricciones, por
ejemplo en el caso de elementos que contienen prosa que requiere
marcado embebido para soportar internacionalización,
entonces la declaración por defecto o una forma
ligeramente restringida de ella puede ser apropiada. El tipo
text descrito en la Sección 5.5 es un ejemplo de un tipo
así que es apropiado para tal propósito.
El Esquema XML proporciona tres elementos
para anotar esquemas para el beneficio de los lectores humanos y
de las aplicaciones. En el esquema de la hoja de pedido, hemos
puesto descripciones básicas e información de
propiedad literaria dentro del elemento documentation [documentación], que es la
ubicación recomendada para el material legible por
humanos. Recomendamos utilizar el atributo xml:lang
con todos los elementos de documentation para indicar el
lenguaje de la información. Alternativamente, puedes
indicar el lenguaje de toda la información en un esquema
poniendo un atributo xml:lang en el elemento
schema.
El elemento appInfo [información para aplicaciones], que
no utilizamos en el esquema de la hoja de pedido, puede
utilizarse para proporcionar información para
herramientas, hojas de estilo y otras aplicaciones. Un ejemplo
interesante de uso de appInfo es un schema
que describe los tipos simples en el documento Esquema XML Parte
2: Tipos de Datos. La información que describe este
esquema, p.e. cuyas propiedades son aplicables a tipos simples
particulares, se representa dentro de los elementos appInfo, y esta
información fue utilizada por una aplicación para
generar texto de forma automática para el documento
Esquema XML Parte 2.
Ambos documentation y appInfo aparecen como
subelementos de annotation [anotación], el cual puede aparecer
por si mismo al principio de la mayoría de construcciones
en esquemas. Para ilustrar esto, el siguiente ejemplo muestra
elementos annotation que aparecen al
principio de una declaración de elemento y una
definición de tipo complejo:
<xsd:element name="precioInternacional">
<xsd:annotation>
<xsd:documentation xml:lang="es">
elemento declarado con tipo anónimo
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:annotation>
<xsd:documentation xml:lang="es">
tipo anónimo vacío con 2 atributos
</xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:attribute name="moneda" type="xsd:string"/>
<xsd:attribute name="valor" type="xsd:decimal"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
El elemento annotation puede aparecer
también al principio de otras construcciones en esquemas
tales como las indicadas por los elementos schema, simpleType, y attribute.
Todas las definiciones de tipos complejos en el esquema de la
hoja de pedido declaran secuencias de elementos que deben
aparecer en el documento instancia. La ocurrencia de elementos
individuales declarada en los llamados modelos de contenido de
esos tipos puede ser opcional, como se indica por un valor de 0
para el atributo minOccurs (p.e. en
comentario), o ser restringidos de otra manera
dependiendo de los valores de minOccurs y maxOccurs. El Esquema XML
también proporciona restricciones que se aplican a grupos
de elementos que aparecen en el modelo de contenido. Estas
restricciones reflejan las disponibles en XML 1.0 y añaden
algunas más. Recordemos que las restricciones no se
aplican a atributos.
El Esquema XML posibilita el que grupos de elementos sean definidos y nombrados, por lo que los elementos pueden ser utilizados para construir modelos de tipos complejos (mimetizando el uso común de entidades parámetro en XML 1.0). También pueden definirse grupos de elementos sin nombre, que junto con elementos en grupos con nombre, pueden ser restringidos para aparecer en el mismos orden (secuencia) en el que son declarados. Alternativamente, pueden ser restringidos de forma que sólo uno de los elementos puede aparecer en la instancia.
Para ilustrar esto, introducimos dos
grupos en la definición de TipoHojaPedido del
esquema de la hoja de pedido por los que las hojas de pedido
pueden contener o bien direcciones de envío y
facturación separadas, o una única dirección
para los casos en los que la persona a la que se factura y
envía sean la misma:
<xsd:complexType name="TipoHojaPedido">
<xsd:sequence>
<xsd:choice>
<xsd:group ref="envioYfacturacion"/>
<xsd:element name="direccionEEUUunica" type="direccionEEUU"/>
</xsd:choice>
<xsd:element ref="comentario" minOccurs="0"/>
<xsd:element name="elementos" type="Elementos"/>
</xsd:sequence>
<xsd:attribute name="fechaPedido" type="xsd:date"/>
</xsd:complexType>
<xsd:group name="envioYfacturacion">
<xsd:sequence>
<xsd:element name="enviarA" type="direccionEEUU"/>
<xsd:element name="facturarA" type="direccionEEUU"/>
</xsd:sequence>
</xsd:group>
El elemento choice
[elección] en un grupo
permite que sólo uno de sus hijos aparezca en la
instancia. Un hijo es un elemento interior de group [grupo] que referencia al grupo llamado
envioYfacturacion consistente en la secuencia de
elementos enviarA, facturarA, y el
segundo hijo es una direccionEEUUunica. Por tanto,
en un documento instancia, el elemento hojaPedido
debe contener o bien un elemento enviarA seguido de
un elemento facturarA o una
direccionEEUUunica. El grupo choice está seguido de las
declaraciones de los elementos comentario y
elementos y tanto el grupo choice como las declaraciones de los
elementos son hijos de el grupo sequence [secuencia]. El efecto de estos grupos es que
el elemento o elementos dirección deben estar seguidos por
elementos comentario y elementos en ese
orden.
Existe una tercera opción para
restringir los elementos de un grupo: todos los elementos de un
grupo pueden aparecer una vez o ninguna, y pueden aparecer en
cualquier orden. El grupo all [todo] (que proporciona una versión
simplificada de conector & de SGML) está limitado al
nivel más alto de cualquier modelo de contenido.
Más aún, los hijos del grupo deben ser todo
elementos individuales (no grupos), y ningún elemento en
el modelo debe aparecer más de una vez, es decir, los
valores permitidos de minOccurs y maxOccurs son 0 y 1. Por
ejemplo, para permitir que elementos hijo de
hojaPedido aparezcan en cualquier orden,
podríamos redefinir TipoHojaPedido como:
<xsd:complexType name="TipoHojaPedido">
<xsd:all>
<xsd:element name="enviarA" type="direccionEEUU"/>
<xsd:element name="facturarA" type="direccionEEUU"/>
<xsd:element ref="comentario" minOccurs="0"/>
<xsd:element name="elementos" type="Elementos"/>
</xsd:all>
<xsd:attribute name="fechaPedido" type="xsd:date"/>
</xsd:complexType>
Por esta definición, un elemento
comentario podría aparecer opcionalmente
dentro de hojaPedido, y puede aparecer antes o
después que cualquier elemento enviarA,
facturarA y elementos, pero sólo
puede aparecer una vez. Más aún, las estipulaciones
de un grupo all no nos
permiten declarar un elemento como comentario fuera
del grupo con el fin de que aparezca más de una vez. El
Esquema XML estipula que un grupo all debe aparecer como hijo
único en el nivel más alto del modelo de contenido.
En otras palabras, lo siguiente no es legal:
<xsd:complexType name="TipoHojaPedido">
<xsd:sequence>
<xsd:all>
<xsd:element name="enviarA" type="direccionEEUU"/>
<xsd:element name="facturarA" type="direccionEEUU"/>
<xsd:element name="elementos" type="Elementos"/>
</xsd:all>
<xsd:sequence>
<xsd:element ref="comentario" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:sequence>
<xsd:attribute name="fechaPedido" type="xsd:date"/>
</xsd:complexType>
Finalmente, los grupos con nombre y sin nombre que aparecen en
modelos de contenido (representado por group y choice, sequence, all respectivamente) pueden tener
atributos minOccurs y maxOccurs. Combinando y
anidando los distintos grupos proporcionados por el Esquema XML,
y utilizando los valores de minOccurs y maxOccurs, es posible
representar cualquier modelo de contenido expresable con un DTD
de XML 1.0. Además, el grupo all proporciona poder expresivo
adicional.
Supongamos que queremos dar más información
acerca de cada elemento en la hoja de pedido, por ejemplo, el
peso de cada elemento y el modo de envío preferido.
Podemos conseguir esto añadiendo las declaraciones de los
atributos pesoKg y enviarPor a la
definición de tipo (anónimo) del elemento
elemento:
<xsd:element name="Elemento" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nombreProducto" type="xsd:string"/>
<xsd:element name="cantidad">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="precioEEUU" type="xsd:decimal"/>
<xsd:element ref="comentario" minOccurs="0"/>
<xsd:element name="fechaEnvio" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="numProducto" type="SKU" use="required"/>
<!-- añadimos los atributos pesoKg y enviarPor -->
<xsd:attribute name="pesoKg" type="xsd:decimal"/>
<xsd:attribute name="enviarPor">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="aire"/>
<xsd:enumeration value="tierra"/>
<xsd:enumeration value="cualquiera"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
Alternativamente, podemos crear un grupo
de atributos con nombre que contenga todos los atributos deseados
de un elemento elemento, y referencie a este grupo
por nombre en la declaración del elemento
elemento:
<xsd:element name="elemento" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nombreProducto" type="xsd:string"/>
<xsd:element name="cantidad">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="precioEEUU" type="xsd:decimal"/>
<xsd:element ref="comentario" minOccurs="0"/>
<xsd:element name="fechaEnvio" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<!-- attributeGroup reemplaza las declaraciones individuales -->
<xsd:attributeGroup ref="EntregaElementos"/>
</xsd:complexType>
</xsd:element>
<xsd:attributeGroup name="EntregaElementos">
<xsd:attribute name="numProducto" type="SKU" use="required"/>
<xsd:attribute name="pesoKg" type="xsd:decimal"/>
<xsd:attribute name="enviarPor">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="are"/>
<xsd:enumeration value="tierra"/>
<xsd:enumeration value="cualquiera"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:attributeGroup>
Utilizando un grupo de atributos de este modo podemos aumentar la legibilidad de los esquemas, y facilitar la actualización de los esquemas porque un grupo de atributos puede ser definido y editado en un lugar y referenciado en múltiples definiciones y declaraciones. Estas características de los grupos de atributos los hacen similares a las entidades parámetro en XML 1.0. Nota que un grupo de atributos puede contener otros grupos de atributos. Y también que las declaraciones de atributos y las de grupos de atributos deben aparecer al final de las declaraciones de tipos complejos.
Uno de los elementos de la hoja de pedido listada en po.xml, el cortaCesped, no
tiene un elemento fechaEnvio. En el contexto de
nuestro escenario, el autor del esquema puede haber hecho dichas
ausencias intencionadamente para indicar elementos
que aún no han sido enviados. Pero en general, la ausencia
de un elemento no tiene un significado particular: puede indicar
que la información es desconocida, o no es aplicable, o el
elemento puede estar ausente por cualquier otra razón. A
veces es deseable representar un elemento no
enviado, información desconocida, o información no
aplicable de manera explícita con un elemento, en
vez de un elemento ausente. Por ejemplo, sería deseable
representar un valor "null" [nulo] que es enviado desde o hacia una base
de datos relacional con un elemento que esté presente.
Tales casos pueden representarse utilizando el mecanismo nulo del
Esquema XML que permite que un elemento pueda aparecer o no con
un valor no-nulo.
El mecanismo nulo del Esquema XML funciona
como una señal nula "fuera de banda". Es otras palabras,
no hay un valor nulo que aparezca como contenido de un elemento,
sino que existe un atributo que indica que el contenido del
elemento es nulo. Para ilustrar esto, modificamos la
declaración del elemento fechaEnvio para que
pueda aceptar valores nulos:
<xsd:element name="fechaEnvio" type="xsd:date" nillable="true"/>
Y para representar explícitamente
que fechaEnvio tiene un valor nulo en el documento
instancia, ponemos el valor del atributo nulo (el del espacio de
nombres del Esquema XML para instancias) a true:
<fechaEnvio xsi:nil="true"></fechaEnvio>
El atributo nil
[nulo] se define como parte del
espacio de nombres para instancias del Esquema XML,
http://www.w3.org/2001/XMLSchema-instance, y
así puede aparecer en el documento instancia con un
prefijo (como xsi:) asociado con ese espacio de
nombres. (Como con el prefijo xsd:, el prefijo
xsi: es utilizado sólo por
convención). Nótese que el mecanismo nulo se aplica
sólo a valores de elementos, y no a valores de atributos.
Un elemento con xsi:nil="true" puede no tener
contenido de elementos pero puede tener atributos.
Un esquema puede ser visto como una
colección (vocabulario) de definiciones de tipos y
declaraciones de elementos cuyos nombres pertenecen a un
determinado espacio de nombres llamado espacio de nombres de
destino. Los espacios de nombres de destino hacen posible la
distinción entre definiciones y declaraciones de
diferentes vocabularios. Por ejemplo, los espacios de nombres de
destino facilitarían la declaración del elemento
element en el
vocabulario del Esquema XML, y la declaración de
element en un hipotético vocabulario de
lenguaje químico. El primero es parte de espacio de
nombres de destino http://www.w3.org/2001/XMLSchema,
y el segundo es parte de otro espacio de nombres de destino.
Cuando queremos comprobar que un documento instancia conforma con uno o más esquemas (a través de un proceso llamado validación del esquema), necesitamos identificar qué declaraciones de elementos y atributos y qué definiciones de tipos en los esquemas deberían utilizarse para según qué tipos en el documento instancia. Los espacios de nombres de destino juegan un papel importante en el proceso de identificación. Examinaremos el papel del espacio de nombres en la próxima sección.
El autor de esquemas tiene diferentes opciones que afectan al modo en el que las identidades de elementos y atributos son representados en documentos instancia. Más específicamente, el autor puede decidir cuando la aparición de elementos y atributos locales en una instancia debe estar o no calificada por un espacio de nombres, utilizando o bien un prefijo explícito o bien implícitamente por defecto. La elección del autor de esquemas en cuanto a calificación de elementos y atributos locales tiene un número de implicaciones en cuanto a las estructuras de los esquemas y de los documentos instancia, y examinaremos algunas de estas implicaciones en las secciones siguientes.
En una versión nueva del esquema de la hoja de pedido,
po1.xsd, declaramos
explícitamente un espacio de nombres, y especificamos que
los elementos y atributos definidos localmente deben estar sin
calificar. El espacio de nombres en po1.xsd es
http://www.example.com/PO1, como indica el valor del
atributo targetNamespace [espacio de nombres de destino].
La calificación de los elementos y atributos locales
puede ser especificada globalmente por un par de atributos,
elementFormDefault
[forma de elemento por defecto] y
attributeFormDefault
[forma de atributo por defecto] ,
en el elemento schema
[esquema], o puede especificarse
de forma separada para cada declaración local utilizando
el atributo form [forma]. Cada uno de los valores de
atributos de ese tipo puede tener el valor
unqualified [sin
calificar] o qualified [calificado], para indicar los casos en los
que los elementos y atributos deben ser calificados o no.
En po1.xsd especificamos
globalmente la calificación de elementos y atributos dando
a elementFormDefault y
attributeFormDefault
el valor unqualified. Hablando estrictamente, esto
no es necesario porque son los valores por defecto de ambos
atributos; los utilizamos aquí para resaltar el contraste
entre este caso y otros casos que serán descritos
más adelante.
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:po="http://www.example.com/PO1"
targetNamespace="http://www.example.com/PO1"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<element name="hojaPedido" type="po:TipoHojaPedido"/>
<element name="comentario" type="string"/>
<complexType name="TipoHojaPedido">
<sequence>
<element name="enviarA" type="po:direccionEEUU"/>
<element name="facturarA" type="po:direccionEEUU"/>
<element ref="po:comentario" minOccurs="0"/>
<!-- etc. -->
</sequence>
<!-- etc. -->
</complexType>
<complexType name="direccionEEUU">
<sequence>
<element name="nombre" type="string"/>
<element name="calle" type="string"/>
<!-- etc. -->
</sequence>
</complexType>
<!-- etc. -->
</schema>
Para ver cómo se construye el espacio de nombres de
este esquema, examinaremos una a una las definiciones de tipos y
declaraciones de elementos. Comenzando por el principio del
esquema, primero definimos un tipo llamado
direccionEEUU que contiene los elementos
nombre, calle, etc. Una consecuencia de
esta definición de tipo es que el tipo
direccionEEUU está incluido en el espacio de
nombres del esquema. A continuación definimos un tipo
denominado TipoHojaPedido que contiene los elementos
enviarA, facturarA,
comentario, etc. TipoHojaPedido
está también incluido en el espacio de nombres del
esquema. Nótese que las referencias de tipos en las
declaraciones de los tres elementos tienen prefijo, es decir,
po:direccionEEUU,po:direccionEEUU y
po:comentario, y el prefijo está asociado con
el espacio de nombres http://www.example.com/PO1.
Este es el mismo espacio de nombres que el del esquema, y por
tanto un procesador de este esquema sabría que tiene que
mirar dentro de este esquema para encontrar la definición
del tipo direccionEEUU y la declaración del
elemento comentario. También es posible
referirse a tipos en otro esquema con un espacio de nombres
diferente, y de esta forma facilitar la reutilización de
las definiciones y declaraciones entre esquemas.
Al principio de po1.xsd,
declaramos los elementos hojaPedido y
comentario. Están incluidos en el espacio de
nombres del esquema. El tipo de elementos hojaPedido
tiene prefijo por la misma razón que
direccionEEUU lo tiene. Por contra, el tipo del
elemento comentario, string, no tiene prefijo. El esquema
po1.xsd contiene una
declaración de espacio de nombre por defecto, y por eso
los tipos sin prefijo como string y los elementos sin prefijo como
element y complexType están
asociados al espacio de nombres por defecto
http://www.w3.org/2001/XMLSchema. De hecho, este es
el espacio de nombres del Esquema en si mismo, y así un
procesador de po1.xsd
sabrá que tiene que mirar dentro del esquema del Esquema
XML -- conocido de otra forma como el "esquema para los esquemas"
-- para encontrar la definición del tipo string y la declaración del elemento
element.
Examinemos cómo el espacio de nombres del esquema afecta a un documento instancia que conforma con él:
<?xml version="1.0"?>
<apo:hojaPedido xmlns:apo="http://www.example.com/PO1"
fechaPedido="1999-10-20">
<enviarA pais="EEUU">
<nombre>Alice Smith</nombre>
<calle>123 Maple Street</calle>
<!-- etc. -->
</enviarA>
<facturarA pais="EEUU">
<nombre>Robert Smith</nombre>
<calle>8 Oak Avenue</calle>
<!-- etc. -->
</facturarA>
<apo:comentario>¡Deprisa, mi césped parece una selva!</apo:comentario>
<!-- etc. -->
</apo:hojaPedido>
El documento instancia declara un espacio de nombres,
http://www.example.com/PO1, y le asocia el prefijo
apo:. Este prefijo es utilizado para calificar dos
elementos en el documento, llamados hojaPedido y
comentario. El espacio de nombres es el mismo que el
espacio de nombres del esquema en po1.xsd, y por tanto un procesador del
documento instancia sabrá buscar en ese esquema las
declaraciones de hojaPedido y
comentario. De hecho, los espacios de nombres se
denominan así por el sentido en el que existe un espacio
de nombres para los elementos hojaPedido y
comentario. Por tanto los espacios de nombres
indicados en el esquema controlan la validación de los
correspondientes espacios de nombres de la instancia.
El prefijo apo: se aplica a los elementos
globales hojaPedido y comentario.
Más aún, elementFormDefault y
attributeFormDefault
requieren que el prefijo no sea aplicado a ninguno de
los elementos declarados localmente tales como
enviarA, facturarA, nombre
y calle, y no es aplicado a ninguno de los
atributos (todos fueron declarados localmente). La
hojaPedido y el comentario son
elementos globales porque están declarados en el contexto
del esquema como un todo en vez de ser declarados dentro del
contexto de un tipo particular. Por ejemplo, la
declaración de hojaPedido aparece como un
hijo del elemento schema en po1.xsd, mientras que la declaración
de enviarA aparece como un hijo del elemento
complexType que
define el TipoHojaPedido.
Cuando no se requiere que los elementos y atributos locales
estén calificados, un autor de instancias puede necesitar
más o menos conocimiento acerca de los detalles del
esquema para crear instancias válidas. Más
específicamente, si el autor puede estar seguro de que
sólo el elemento raíz (como
hojaPedido) es global, entonces es un caso simple en
el que sólo hay que calificar el elemento raíz. En
otro caso, el autor puede saber que todos los elementos
están declarados globalmente, y por tanto todos los
elementos de la instancia pueden tener prefijo, quizás
aprovechando una declaración de espacio de nombres por
defecto. (Examinaremos esta aproximación en la Sección 3.3). Por otra parte, si no
hay un patrón uniforme de declaraciones locales y
globales, el autor necesitará conocimiento detallado del
esquema para asignar los prefijos a los elementos y atributos
globales de forma correcta.
Los elementos y atributos pueden calificarse de forma
independiente, aunque empezaremos describiendo la
calificación de elementos locales. Para especificar que
todos los elementos declarados localmente en un esquema deben
estar calificados, ponemos el valor de elementFormDefault a
qualified:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:po="http://www.example.com/PO1"
targetNamespace="http://www.example.com/PO1"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<element name="hojaPedido" type="po:TipoHojaPedido"/>
<element name="comentario" type="string"/>
<complexType name="TipoHojaPedido">
<!-- etc. -->
</complexType>
<!-- etc. -->
</schema>
Y en esta instancia que conforma con el esquema, calificamos todos los elementos explícitamente:
<?xml version="1.0"?>
<apo:hojaPedido xmlns:apo="http://www.example.com/PO1"
fechaPedido="1999-10-20">
<apo:enviarA pais="EEUU">
<apo:nombre>Alice Smith</apo:nombre>
<apo:calle>123 Maple Street</apo:calle>
<!-- etc. -->
</apo:enviarA>
<apo:facturarA country="US">
<apo:nombre>Robert Smith</apo:nombre>
<apo:street>8 Oak Avenue</apo:alle>
<!-- etc. -->
</apo:facturarA>
<apo:comentario>¡Deprisa, mi césped parece una selva!</apo:comentario>
<!-- etc. -->
</apo:hojaPedido>
De forma alternativa, podemos reemplazar la
calificación explícita de cada elemento por una
calificación implícita proporcionada por el espacio
de nombres por defecto, como se muestra aquí en po2.xml:
<?xml version="1.0"?>
<hojaPedido xmlns="http://www.example.com/PO1"
fechaPedido="1999-10-20">
<envarA pais="EEUU">
<nombre>Alice Smith</nombre>
<calle>123 Maple Street</calle>
<!-- etc. -->
</shipTo>
<facturarA pais="EEUU">
<nombre>Robert Smith</nombre>
<calle>8 Oak Avenue</calle>
<!-- etc. -->
</facturarA>
<comentario>¡Deprisa, mi césped parece una selva!</comentario>
<!-- etc. -->
</hojaPedido>
En po2.xml, todos los
elementos de la instancia pertenecen al mismo espacio de nombres,
y la declaración de espacio de nombres estipula un espacio
de nombres por defecto que se aplica a todos los elementos de la
instancia. Por tanto, no es necesario utilizar prefijo de forma
explícita para ninguno de los elementos. Como otra
ilustración del uso de elementos calificados, los esquemas
de la Sección 5 requieren
todos elementos calificados.
La calificación de atributos es muy similar a la de
elementos. Los atributos que deben ser calificados, ya sea porque
han sido declarados globalmente o porque el atributo attributeFormDefault
tiene un valor qualified, aparecen con prefijo en
los documentos instancia. Un ejemplo de un atributo calificado es
el atributo xsi:nil
que fue introducido en la Sección 2.9.
De hecho, los atributos que requieren ser calificados deben
prefijarse explícitamente porque la especificación
XML-Namespaces
[Espacios de Nombres XML] no
proporciona un mecanismo para poner por defecto los espacio de
nombres de los atributos. Los atributos que no requieren ser
calificados aparecen en los documentos instancia sin prefijos,
que es el caso típico.
El mecanismo de calificación que
hemos descrito hasta ahora ha controlado todas las declaraciones
de elementos y atributos dentro de un espacio de nombres
particular. También es posible controlar la
calificación en base a cada una de las declaraciones en
particular utilizando el atributo form. Por ejemplo, para requerir que
el atributo declarado localmente clavePublica sea
calificado en instancias, lo declaramos del siguiente modo:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:po="http://www.example.com/PO1"
targetNamespace="http://www.example.com/PO1"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<!-- etc. -->
<element name="seguro">
<complexType>
<sequence>
<!-- declaraciones de elementos -->
</sequence>
<attribute name="clavePublica" type="base64Binary" form="qualified"/>
</complexType>
</element>
</schema>
Nótese que el valor del atributo form sustituye el valor del atributo
attributeFormDefault
solamente para el atributo clavePublica. El atributo
form también
puede ser aplicado a una declaración de elemento de la
misma forma. Un documento instancia que conforma con el esquema
es:
<?xml version="1.0"?>
<hojaPedido xmlns="http://www.example.com/PO1"
xmlns:po="http://www.example.com/PO1"
fechaPedido="1999-10-20">
<!-- etc. -->
<seguro po:clavePublica="GpM7">
<!-- etc. -->
</seguro>
</hojaPedido>
Otro estilo de autoría, aplicable cuando los nombres de
todos los elementos son únicos dentro de un espacio de
nombres, es crear esquemas en los que todos los elementos son
globales. Esto tiene un efecto similar al uso de <!ELEMENT>
en un DTD. En el ejemplo siguiente hemos modificado el po1.xsd original de forma que todos
los elementos son declarados globalmente. Advierte que hemos
omitido los atributos elementFormDefault y
attributeFormDefault
en este ejemplo para enfatizar que sus valores son irrelevantes
cuando sólo existen declaraciones globales de elementos y
atributos.
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:po="http://www.example.com/PO1"
targetNamespace="http://www.example.com/PO1">
<element name="hojaPedido" type="po:TipoHojaPedido"/>
<element name="enviarA" type="po:direccionEEUU"/>
<element name="facturarA" type="po:direccionEEUU"/>
<element name="comentario" type="string"/>
<element name="nombre" type="string"/>
<element name="calle" type="string"/>
<complexType name="TipoHojaPedido">
<sequence>
<element ref="po:enviarA"/>
<element ref="po:facturarA"/>
<element ref="po:comentario" minOccurs="0"/>
<!-- etc. -->
</sequence>
</complexType>
<complexType name="direccionEEUU">
<sequence>
<element ref="po:nombre"/>
<element ref="po:calle"/>
<!-- etc. -->
</sequence>
</complexType>
<!-- etc. -->
</schema>
Esta versión "global" de po1.xsd validará el documento
instancia po2.xml, el cual,
como describimos anteriormente, también valida contra el
esquema la versión "calificada" de po1.xsd. En otras palabras, ambas formas de
esquema, pueden validar el mismo documento con espacio de nombres
por defecto. Así, en un aspecto ambas formas del esquema
son similares, aunque en otro importante aspecto ambas formas son
muy diferentes. Específicamente, cuando todos los
elementos son declarados globalmente, no es posible tener la
ventaja de los nombres locales. Por ejemplo, sólo puedes
declarar un elemento global llamado "titulo". Sin embargo, puedes
declarar localmente un elemento llamado "titulo" que sea de tipo
string, y sea un subelemento de "libro". Dentro del mismo esquema
(espacio de nombres) puedes declarar un segundo elemento
también llamado "titulo" que sea una enumeración de
los valores "Sr Sra Srta".
En la Sección 2 explicamos la base del Esquema XML utilizando un esquema que no declaraba un espacio de nombres y un documento instancia que tampoco declaraba un espacio de nombres. Así que la pregunta surge de forma natural: ¿Cual es el espacio de nombres en esos ejemplos y cómo se referencia?
En el esquema de la hoja de pedido, po.xsd, no declaramos un espacio de nombres
para el esquema, ni tampoco declaramos un prefijo (como
po: más arriba) asociado con el espacio de
nombres del esquema con el que podríamos referenciar tipos
y elementos definidos y declarados en el esquema. La consecuencia
de no declarar un espacio de nombres en un esquema es que las
definiciones y declaraciones de ese esquema, tales como
direccionEEUU y hojaPedido, son
referenciadas sin calificación del espacio de nombres. En
otras palabras, no hay un prefijo explícito de un espacio
de nombres ni hay ningún espacio de nombres
implícito aplicado a la referencia por defecto.
Así, por ejemplo, el elemento hojaPedido es
declarado utilizando como referencia el tipo
TipoHojaPedido. Por contra, todos los elementos y
tipos del Esquema XML utilizados en po.xsd están explícitamente
calificados con el prefijo xsd: que está
asociado con el espacio de nombres del Esquema XML.
En los casos en los que el esquema es diseñado sin un
espacio de nombres, se recomienda encarecidamente que todos los
elementos y tipos del Esquema XML sean calificados
explícitamente con un prefijo que esté
asociado con el espacio de nombres del Esquema XML tal como
xsd: (como en po.xsd). El razonamiento para esta
recomendación es que si los tipos y elementos del Esquema
XML están asociados al espacio de nombres del Esquema XML
por defecto, es decir, sin prefijos, entonces las referencias a
los tipos del Esquema XML pueden no ser distinguibles de las
referencias de tipos definidos por el usuario.
Las declaraciones de elementos de un esquema sin espacio de
nombres determinado validan elementos sin calificar en el
documento instancia. Esto es, validan elementos para los que no
se ha proporcionado calificación de espacio de nombres con
prefijo explícito ni por defecto (xmlns:).
Así, para validar un documento tradicional XML 1.0 que no
utiliza ningún tipo de espacio de nombres, debes utilizar
un esquema sin espacio de nombres. Por supuesto, hay muchos
documentos XML 1.0 que no utilizan espacios de nombres,
así que habrá muchos documentos esquema escritos
sin ningún espacio de nombres; debes asegurarte de dar a
tu procesador un documento esquema que se corresponda con el
vocabulario que deseas validar.
El esquema de la hoja de pedido descrito en el Capítulo 2 estaba contenido en un único documento, y la mayoría de construcciones de los esquemas --tales como declaraciones de elementos y definiciones de tipos -- fueron construidas desde cero. En realidad, los autores de esquemas desearán componer esquemas a partir de construcciones localizadas en múltiples documentos, y crear tipos nuevos basados en tipos existentes. En esta sección, examinamos los mecanismos que posibilitan tales composiciones y creaciones.
A medida que los esquemas se hacen más grandes, es a
menudo deseable dividir su contenido entre varios documentos
esquema con propósitos tales como facilitar su
mantenimiento, control de acceso, y legibilidad. Por estas
razones, hemos sacado fuera de po.xsd las construcciones de esquema
relativas a direcciones, y las hemos puesto en un fichero nuevo
llamado address.xsd. El
esquema de la hoja de pedido modificada se llama ipo.xsd:
<schema targetNamespace="http://www.example.com/IPO"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ipo="http://www.example.com/IPO">
<annotation>
<documentation xml:lang="es">
Esquema de la Hoja de Pedido Internacional para Example.com
Copyright 2000 Example.com. Todos los derechos reservados.
</documentation>
</annotation>
<!-- inclusión de las construcciones de direcciones -->
<include
schemaLocation="http://www.example.com/schemas/address.xsd"/>
<element name="hojaPedido" type="ipo:TipoHojaPedido"/>
<element name="comentario" type="string"/>
<complexType name="TipoHojaPedido">
<sequence>
<element name="enviarA" type="ipo:Direccion"/>
<element name="facturarA" type="ipo:Direccion"/>
<element ref="ipo:comentario" minOccurs="0"/>
<element name="elementos" type="ipo:Elementos"/>
</sequence>
<attribute name="fechaPedido" type="date"/>
</complexType>
<complexType name="Elementos">
<sequence>
<element name="elemento" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="nombreProducto" type="string"/>
<element name="cantidad">
<simpleType>
<restriction base="positiveInteger">
<maxExclusive value="100"/>
</restriction>
</simpleType>
</element>
<element name="precioEEUU" type="decimal"/>
<element ref="ipo:comentario" minOccurs="0"/>
<element name="fechEnvio" type="date" minOccurs="0"/>
</sequence>
<attribute name="numProducto" type="ipo:SKU" use="required"/>
</complexType>
</element>
</sequence>
</complexType>
<simpleType name="SKU">
<restriction base="string">
<pattern value="\d{3}-[A-Z]{2}"/>
</restriction>
</simpleType>
</schema>
El archivo que contiene las construcciones es:
<schema targetNamespace="http://www.example.com/IPO"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ipo="http://www.example.com/IPO">
<annotation>
<documentation xml:lang="es">
Direcciones para la Hoja de Pedido Internacional.
Copyright 2000 Example.com. Todos los derechos reservados.
</documentation>
</annotation>
<complexType name="Direccion">
<sequence>
<element name="nombre" type="string"/>
<element name="calle" type="string"/>
<element name="ciudad" type="string"/>
</sequence>
</complexType>
<complexType name="direccionEEUU">
<complexContent>
<extension base="ipo:Direccion">
<sequence>
<element name="estado" type="ipo:estadoEEUU"/>
<element name="zip" type="positiveInteger"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="direccionUK">
<complexContent>
<extension base="ipo:Direccion">
<sequence>
<element name="codigoPostal" type="ipo:codigoPostalUK"/>
</sequence>
<attribute name="codigoExportacion" type="positiveInteger" fixed="1"/>
</extension>
</complexContent>
</complexType>
<!-- otras derivaciones de Direcciones para más paises -->
<simpleType name="estadoEEUU">
<restriction base="string">
<enumeration value="AK"/>
<enumeration value="AL"/>
<enumeration value="AR"/>
<!-- y así los demás ... -->
</restriction>
</simpleType>
<!-- definición de tipo simple para codigoPostalUK -->
</schema>
Las diferentes construcciones para hojas
de pedido y direcciones están ahora contenidas en dos
archivos de esquemas distintos, ipo.xsd y address.xsd. Para incluir estas
construcciones como parte del esquema de la hoja de pedido
internacional, en otras palabras, para incluirlas en el espacio
de nombres de la hoja de pedido internacional, ipo.xsd contiene el elemento include:
<include schemaLocation="http://www.example.com/schemas/address.xsd"/>
El efecto de este elemento include es incluir las definiciones
y declaraciones contenidas en address.xsd, y hacer que estén
disponibles como parte del espacio de nombres del esquema de la
hoja de pedido internacional. La única advertencia de
importancia a tener en cuenta al utilizar include es que el espacio de
nombres de los componentes incluidos debe ser el mismo que el
espacio de nombres del esquema incluido, en este caso
http://www.example.com/IPO. Incluir definiciones y
declaraciones mediante el mecanismo que proporciona include, añade estos
componentes realmente al espacio de nombres existente. En la Sección 4.5, describiremos un
mecanismo similar que hace posible que se puedan modificar
ciertos componentes una vez incluidos.
En nuestro ejemplo, hemos mostrado sólo un documento
incluido y un documento que lo incluye. En la práctica es
posible incluir más de un documento utilizando
múltiples elementos include, y los documentos pueden
incluir a otros que a su vez incluyen otros documentos. Sin
embargo, anidar documentos de esta manera es sólo legal si
todas las partes incluidas en el esquema están incluidas
en el mismo espacio de nombres.
Los documentos instancia que conforman con el esquema cuyas
definiciones se extienden por múltiples documentos
esquema, sólo necesitan referenciar al esquema de 'mayor
nivel' y al espacio de nombres común, y es responsabilidad
del procesador el unir todas las definiciones incluidos en los
distintos documentos. En nuestro ejemplo de antes, el documento
instancia ipo.xml (ver Sección 4.3) sólo
hace referencia al espacio de nombres común,
http://www.example.com/IPO, y (por
implicación) al archivo de esquema
http://www.example.com/schemas/ipo.xsd. El
procesador es el responsable de obtener el archivo de esquema
address.xsd.
En la Sección 5.4 describiremos cómo los esquemas pueden utilizarse para validar contenido de más de un espacio de nombres.
Para crear nuestras construcciones de direcciones, comenzamos
creando un tipo complejo llamado Direccion del modo
usual (ver address.xsd).
El tipo Direccion contiene los elementos
básicos de una dirección: un nombre, una calle y
una ciudad. (Tal definición no funcionará para
todos los países, pero sirve para el propósito de
nuestro ejemplo). Desde este punto de inicio derivamos dos nuevos
tipos complejos que contienen todos los elementos del tipo
original y elementos adicionales que son específicos para
las direcciones de EEUU y las de UK. La técnica que
utilizamos aquí para derivar nuevos tipos (complejos) de
direcciones extendiendo un tipo existente es la misma
técnica que utilizamos en la Sección 2.5.1, excepto porque
nuestro tipo base aquí es un tipo complejo mientras que
nuestro tipo base en la sección mencionada era un tipo
simple.
Definimos dos tipos complejos nuevos,
direccionEEUU y direccionUK, utilizando
el elemento complexType. Además
indicamos que los modelos de contenido de los nuevos tipos son
complejos, es decir, contienen elementos, e indicamos que estamos
extendiendo el tipo base Direccion por el valor del
atributo base en el
elemento extension.
Cuando un elemento complejo se deriva por extensión, su
modelo de contenido efectivo es el modelo de contenido del tipo
base añadiéndole el modelo de contenido
especificado en la derivación del tipo. Es más, los
dos modelos de contenido son tratados como dos hijos de un grupo
secuencial. En el caso de direccionUK, el modelo de
contenido de direccionUK es el modelo de contenido
de Direccion añadiéndole las
declaraciones para un elemento codigoPostal y un
atributo codigoExportacion. Esto es como definir la
direccionUK desde cero como sigue:
<complexType name="direccionUK"> <sequence> <!-- modelo de contenido de Direccion --> <element name="nombre" type="string"/> <element name="calle" type="string"/> <element name="ciudad" type="string"/> <!-- declaración de elemento añadida --> <element name="codigoPostal" type="ipo:codigoPostalUK"/> </sequence> <!-- declaración de atributo añadida --> <attribute name="codigoExportacion" type="positiveInteger" fixed="1"/> </complexType>
En nuestro caso de ejemplo, las hojas de pedido son generadas
en respuesta a pedidos de clientes lo que puede incluir
direcciones de envío y facturación en diferentes
países. La hoja de pedido internacional de abajo, ipo.xml, ilustra un caso así en
el que los productos son enviados a UK y la factura es enviada a
una dirección de EEUU. Claramente es mejor si el esquema
para hojas de pedido internacionales no tiene que especificar
cada posible combinación de direcciones internacionales
para facturación y envío, e incluso aún
mejor si podemos añadir nuevos tipos complejos de
direcciones internacionales sin más que crear nuevas
derivaciones de Direccion.
El Esquema XML nos permite definir los
elementos facturarA y enviarA como
tipos Direccion (ver ipo.xsd) pero utilizar instancias de
direcciones internacionales en lugar de instancias de
Direccion. En otras palabras, un documento instancia
cuyo contenido conforme con el tipo direccionUK
será válido si el contenido aparece dentro del
documento en un lugar en el que se espera la aparición de
una Direccion (asumiendo que el contenido de la
direccionUK es válido en si mismo). Para
hacer que esta característica del esquema funcione, y para
identificar exactamente qué tipo derivado se pretende
utilizar, el tipo derivado debe ser identificado en el documento
instancia. El tipo se identifica utilizando el atributo xsi:type que es parte del
espacio de nombres de la instancia del Esquema XML. En el
ejemplo, el uso de ipo.xml de
los tipos derivados direccionUK y
direccionEEUU se identifica a través de los
valores asignados a los atributos xsi:type.
<?xml version="1.0"?>
<ipo:hojaPedido
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ipo="http://www.example.com/IPO"
fechaPedido="1999-12-01">
<enviarA codigoExportacion="1" xsi:type="ipo:direccionUK">
<nombre>Helen Zoe</nombre>
<calle>47 Eden Street</calle>
<ciudad>Cambridge</ciudad>
<codigoPostal>CB1 1JR</codigoPostal>
</enviarA>
<facturarA xsi:type="ipo:direccionEEUU">
<nombre>Robert Smith</nombre>
<calle>8 Oak Avenue</calle>
<ciudad>Old Town</estado>
<estado>PA</state>
<zip>95819</zip>
</facturarA>
<elementos>
<elemento numProducto="833-AA">
<nombreProducto>Collar de Lapis</nombreProducto>
<cantidad>1</cantidad>
<precioEEUU>99.95</precioEEUU>
<ipo:comentario>¡Lo quiero para las vacaciones!</ipo:comentario>
<fechaEnvio>1999-12-05</fechaEnvio>
</elemento>
</elementos>
</ipo:hojaPedido>
En la Sección 4.8 describiremos como prevenir el que los tipos derivados sean utilizados en este tipo de sustituciones.
En adición a la derivación de tipos complejos nuevos por extensión de modelos de contenido, es posible derivar tipos nuevos por restricción de modelos de contenido de tipos existentes. La restricción de tipos complejos es conceptualmente igual que la restricción de tipos simples, excepto en que la restricción de tipos complejos implica a las declaraciones de un tipo en vez de el rango de valores aceptable que utiliza un tipo simple. Un tipo complejo derivado por restricción es muy parecido a su tipo base, excepto en que sus declaraciones están más limitadas que las declaraciones correspondientes de su tipo base. De hecho, los valores representados por el tipo nuevo son un subconjunto de los valores representados por el tipo base (como en el caso de restricción de tipos simples). En otras palabras, una aplicación preparada para los valores del tipo base no se verá sorprendida por los valores del tipo derivado.
Por ejemplo, supongamos que queremos actualizar nuestra
definición de la lista de elementos en una
hoja de pedido internacional para que deba contener al
menos un elemento en el pedido, el esquema
mostrado en ipo.xsd permite
que un elemento elementos aparezca sin ningún
elemento hijo elemento. Para crear nuestro tipo
nuevo ElementosConfirmados, definimos el tipo del
modo habitual, indicando que es derivado por restricción
del tipo base Elementos y proporciona un valor nuevo
(más restrictivo) para el número mínimo de
ocurrencias del elemento elemento. Nótese que
los tipos derivados por restricción deben todos los
componentes de la definición del tipo base que deben ser
incluidos en el tipo derivado:
<complexType name="ElementosConfirmados">
<complexContent>
<restriction base="ipo:Elementos">
<sequence>
<!-- el elemento es diferente que en Elementos -->
<element name="elemento" minOccurs="1" maxOccurs="unbounded">
<!-- el resto de la definición es el mismo de Elementos -->
<complexType>
<sequence>
<element name="nombreProducto" type="string"/>
<element name="cantidad">
<simpleType>
<restriction base="positiveInteger">
<maxExclusive value="100"/>
</restriction>
</simpleType>
</element>
<element name="precioEEUU" type="decimal"/>
<element ref="ipo:comentario" minOccurs="0"/>
<element name="fechaEnvio" type="date" minOccurs="0"/>
</sequence>
<attribute name="numProducto" type="ipo:SKU" use="required"/>
</complexType>
</element>
</sequence>
</restriction>
</complexContent>
</complexType>
Este cambio, requiriendo uno o más elementos hijo en
vez de permitir cero o más elementos hijo, restringe el
número de elementos hijo permitidos de un mínimo de
0 a un mínimo de 1. Nótese que todos los elementos
de tipo ElementosConfirmados serán
también aceptables como elementos de tipo
Elemento.
Para ilustrar aún más esta restricción, la Tabla 3 muestra varios ejemplos de cómo pueden restringirse las declaraciones de elementos y atributos en las definiciones de tipos (la tabla muestra sintaxis de elementos aunque los tres primeros ejemplos son restricciones de atributos igualmente válidas).
| Tabla 3. Ejemplos de Restricción | ||
|---|---|---|
| Base | Restricción | Notas |
| default="1" | establece un valor por defecto donde antes no había ninguno establecido | |
| fixed="100" | establece un valor fijo donde antes no había ninguno establecido | |
| type="string" | especifica un tipo donde antes no había ninguno establecido | |
| (minOccurs, maxOccurs) | (minOccurs, maxOccurs) | |
| (0, 1) | (0, 0) |
exclusión de un componente opcional, esto también puede conseguirse omitiendo la declaración del componente de la definición del tipo restringido |
| (0, unbounded) | (0, 0) (0, 37) | |
| (1, 9) | (1, 8) (2, 9) (4, 7) (3, 3) | |
| (1, unbounded) | (1, 12) (3, unbounded) (6, 6) | |
| (1, 1) | - | no se pueden restringir ni minOccurs ni maxOccurs |
En la Sección 4.1
describimos cómo incluir definiciones y declaraciones
obtenidas de archivos de esquema externos que tienen el mismo
espacio de nombres. El mecanismo include facilita el uso de
componentes de esquema creados externamente "tal cual", esto es,
sin ninguna modificación. Acabamos de describir
cómo derivar tipos por restricción y por
extensión, y el mecanismo redefine que describimos
aquí posibilita la redefinición de tipos complejos
y simples, de grupos, y de grupos de atributos que se obtienen de
archivos de esquema externos. Al igual que el mecanismo include, redefine requiere que los
componentes externos estén en el mismo espacio de nombres
que el esquema que los va a redefinir, aunque los componentes
externos que no tienen espacio de nombres alguno, también
pueden ser redefinidos. En éste último caso, los
componentes externos redefinidos se hacen parte del espacio de
nombres del esquema que los redefine.
Para ilustrar el mecanismo redefine, lo utilizamos en lugar
del mecanismo include
en el esquema de la Hoja de Pedido Internacional, ipo.xsd, y lo utilizamos para modificar la
definición del tipo complejo Direccion
contenida en address.xsd:
<schema targetNamespace="http://www.example.com/IPO"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ipo="http://www.example.com/IPO">
<!-- incluimos las construcciones de direcciones -->
<redefine
schemaLocation="http://www.example.com/schemas/address.xsd">
<!-- redefinición de Direccion -->
<complexType name="Direccion">
<complexContent>
<extension base="ipo:Direccion">
<sequence>
<element name="pais" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
</redefine>
<!-- etc. -->
</schema>
El elemento redefine actúa de forma muy
parecida al elemento include ya que incluye todas las
declaraciones y definiciones del archivo address.xsd. La definición de
tipo complejo de Direccion utiliza la sintaxis de
extensión familiar para añadir un elemento
pais a la definición de
Direccion. De todas formas, el tipo base es
también Direccion. Fuera del elemento
redefine, cualquier
intento de definir un tipo complejo con el mismo nombre (y el
mismo espacio de nombres) como el tipo base del que está
siendo derivado, causa un error. Pero en este caso, no hay tal
error, y la definición extendida de Direccion
se convierte en la única definición de
Direccion.
Ahora que Direccion ha sido redefinido, la
extensión se aplica a todos los componentes del esquema
que hacen uso de Direccion. Por ejemplo, address.xsd contiene definiciones
de tipos de direcciones internacionales que se derivan de
Direccion. Estas derivaciones reflejan el tipo
address.xsd redefinido,
como se muestra en el siguiente fragmento:
.... <enviarA exportCode="1" xsi:type="ipo:direccionUK"> <nombre>Helen Zoe</nombre> <calle>47 Eden Street</calle> <ciudad>Cambridge</ciudad> <!-- pais fue añadido a Direccion que es el tipo base de direccionUK --> <pais>United Kingdom</pais> <!-- codigoPostal fue añadido como parte de direccionUK --> <codigoPostal>CB1 1JR</codigoPostal> </enviarA> ....
Nuestro ejemplo ha sido cuidadosamente construido de manera
que el tipo redefinido Direccion no entra en
conflicto en modo alguno con los tipos que son derivados de la
definición original de Direccion. Pero
nótese que sería muy fácil crear un
conflicto. Por ejemplo, si las derivaciones del tipo
dirección internacional hubiesen extendido
Direccion añadiendo un elemento
pais, entonces la redefinición de
Direccion estaría añadiendo un
elemento del mismo nombre al modelo de contenido de
Direccion. Es ilegal tener dos elementos del mismo
nombre (y en el mismo espacio de nombres) pero diferentes tipos
en un modelo de contenido, y así el intento de redefinir
Direccion causaría un error. En general,
redefine no protege
de tales errores, y debería ser utilizado con cuidado.
El Esquema XML proporciona un mecanismo,
llamado grupos de sustitución, que permite que los
elementos sean sustituidos por otros elementos. De forma
más específica, los elementos pueden ser asignados
a un grupo especial de elementos que son sustuituibles por un
elemento particular llamado el elemento cabecera. (Nótese
que el elemento cabecera debe ser declarado como un elemento
global). Para ilustrarlo, declaramos dos elementos llamados
comentarioCliente y comentarioEnvio y
los asignamos a un grupo de sustitución cuyo elemento
cabecera es comentario y así
comentarioCliente y comentarioEnvio
pueden ser utilizados en cualquier lugar en el que
pudiésemos utilizar comentario. Los elementos
de los grupos de sustitución deben tener el mismo tipo que
el elemento cabecera, o pueden tener un tipo que haya sido
derivado del tipo del elemento cabecera. Para declarar estos dos
nuevos elementos, y para hacerlos sustituibles por el elemento
comentario, utilizamos la siguiente sintaxis:
<element name="comentarioEnvio" type="string"
substitutionGroup="ipo:comentario"/>
<element name="comentarioCliente" type="string"
substitutionGroup="ipo:comentario"/>
Cuando estas declaraciones son añadidas al esquema de
la hoja de pedido internacional, comentarioCliente y
comentarioEnvio pueden ser sustituidos por
comentario en el documento instancia, por
ejemplo:
....
<elementos>
<elemento numProducto="833-AA">
<nombreProducto>Collar de Lapis</nombreProducto>
<cantidad>1</cantidad>
<precioEEUU>99.95</precioEEUU>
<ipo:comentarioEnvio>
Utilizar recubrimiento de oro si es posible
</ipo:comentarioEnvio>
<ipo:comentarioCliente>
¡Lo quiero para las vacaciones!
</ipo:comentarioCliente>
<fechaEnvio>1999-12-05</fechaEnvio>
</elemento>
</elementos>
....
Nótese que cuando un documento instancia contiene
sustituciones de elementos cuyos tipos son derivados de los de
sus elementos cabecera, no es necesario identificar los
tipos derivados utilizando la construcción xsi:type que describimos en la
Sección 4.3.
La existencia de un grupo de sustitución no requiere que ninguno de los elementos de la clase sea utilizado, ni excluye el uso de un elemento cabecera. Simplemente proporciona un mecanismo para permitir los elementos ser usados de forma intercambiable.
El Esquema XML proporciona un mecanismo
para forzar la sustitución de un elemento o tipo
particular. Cuando un elemento o tipo se declara como
"abstracto", no puede ser utilizado en un documento instancia.
Cuando un elemento se declara como abstracto, un miembro de su
grupo de sustitución debe aparecer en el documento
instancia. Cuando la definición de tipo correspondiente a
un elemento es declarada como abstracta, todas las instancias de
ese elemento deben utilizar xsi:type para indicar cualquier
tipo derivado que no sea abstracto.
En el ejemplo de grupo de sustitución descrito en la Sección 4.6, sería
útil deshabilitar el uso del elemento
comentario para que las instancias deban hacer uso
de los elementos comentarioCliente y
comentarioEnvio. Para declarar el elemento
comentario como abstracto, modificamos su
declaración original en el esquema de la orden de pedido
internacional, ipo.xsd, como
sigue:
<element name="comentario" type="string" abstract="true"/>
Con comentario declarado como abstracto, ahora
las instancias de las hojas de pedido internacional son
sólo válidas si contienen elementos
comentarioCliente y
comentarioEnvio.
Declarar un elemento como abstracto requiere el uso de un
grupo de sustitución. Declarar un tipo como abstracto
requiere simplemente el uso de un tipo derivado de él (e
identificado por el atributo xsi:type) en el documento
instancia. Considérese la siguiente definición de
esquema:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://cars.example.com/schema"
xmlns:destino="http://cars.example.com/schema">
<complexType name="Vehiculo" abstract="true"/>
<complexType name="Coche">
<complexContent>
<extension base="destino:Vehiculo"/>
</complexContent>
</complexType>
<complexType name="Avion">
<complexContent>
<extension base="destino:Vehiculo"/>
</complexContent>
</complexType>
<element name="transporte" type="target:Vehiculo"/>
</schema>
El elemento transporte no es abstracto, por tanto
puede aparecer en documentos instancia. De todas formas, como su
definición de tipo es abstracta, nunca podrá
aparecer en un documento instancia si el atributo xsi:type que se refiere a un
tipo derivado. Eso significa que lo siguiente no es
esquema-válido:
<transporte xmlns="http://cars.example.com/schema"/>
porque el tipo del elemento transporte es
abstracto. Sin embargo, lo siguiente sí es
esquema-válido:
<transporte xmlns="http://cars.example.com/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="Car"/>
porque utiliza un tipo no abstracto que es sustituible por
Vehiculo.
Hasta ahora, hemos podido derivar tipos nuevos y utilizarlos en documentos instancia sin ningún tipo de impedimento. En realidad, los autores de esquemas querrán controlar en ocasiones las derivaciones de tipos particulares, y el uso de tipos derivados en instancias.
El Esquema XML proporciona un par de mecanismos que controlan
la derivación de tipos. Uno de esos mecanismos permite al
autor de esquemas especificar que para un tipo complejo
particular, los tipos nuevos no puedan derivar de él, bien
por (a) restricción o bien por (b) extensión o (c)
de ninguna manera. Para ilustrarlo supongamos que no queremos
permitir que se pueda derivar del tipo Direccion por
restricción porque pretendemos que sólo sea
utilizado como tipo base para tipos extendidos como
direccionEEUU y direccionUK. Para
prevenir tales derivaciones, modificaremos un poco la
definición original de direccionEEUU como
sigue:
<complexType name="Direccion" final="restriction"> <sequence> <element name="nombre" type="string"/> <element name="calle" type="string"/> <element name="ciudad" type="string"/> </sequence> </complexType>
El valor restriction del
atributo final
previene las derivaciones por restricción. La
prevención de las derivaciones del todo, o por
extensión, se indica con los valores #all y
extension respectivamente. Más aún,
existe un atributo opcional finalDefault en el elemento
schema cuyo valor
puede ser uno de los valores permitidos para el atributo final. El efecto de
especificar un atributo finalDefault es equivalente
al de especificar un atributo final para cada definición
de tipo y declaración de elemento en el esquema.
Otro tipo para el control de la
derivación de tipos, controla las propiedades que pueden
ser aplicadas en la derivación de un tipo simple nuevo.
Cuando un tipo simple es definido, el atributo fixed puede ser aplicado a
cualquiera de sus propiedades para prevenir que la
derivación de ese tipo modifique el valor de esas
propiedades fijadas. Por ejemplo, podemos definir un tipo simple
codigoPostal como:
<simpleType name="codigoPostal">
<restriction base="string">
<length value="7" fixed="true"/>
</restriction>
</simpleType>
Una vez que este tipo simple ha sido definido, podemos derivar un tipo nuevo de código postal en el que aplicamos una propiedad no fijada en la definición, por ejemplo:
<simpleType name="codigoPostalUK">
<restriction base="ipo:codigoPostal">
<pattern value="[A-Z]{2}\d\s\d[A-Z]{2}"/>
</restriction>
</simpleType>
Sin embargo, no podemos derivar un código postal nuevo en el que re-apliquemos cualquier propiedad que fuese fijada en la definición del tipo base:
<simpleType name="codigoPostalUK">
<restriction base="ipo:codigoPostal">
<pattern value="[A-Z]{2}\d\d[A-Z]{2}"/>
<!-- intento ilegal de modificar la propiedad fijada en el tipo base -->
<length value="6" fixed="true"/>
</restriction>
</simpleType>
Además de los mecanismos que
controlan las derivaciones de tipo, el Esquema XML proporciona un
mecanismo que controla qué derivaciones y grupos de
sustitución pueden ser usados en documentos instancia. En
la Sección 4.3,
describimos cómo los tipos derivados
direccionEEUU y direccionUK,
podrían ser utilizados por los elementos
enviarA y facturarA en documentos
instancia. Estos tipos derivados pueden reemplazar el modelo de
contenido proporcionado por el tipo Direccion porque
se derivan del tipo Direccion. Sin embargo, el
reemplazo por tipos derivados puede controlarse utilizando el
atributo block [bloqueo] en una definición de
tipo. Por ejemplo, si queremos bloquear cualquier
derivación por restricción para que no sea usada en
el lugar de Direccion (quizás por la misma
razón por la que definimos Direccion con
final="restriction"),
podemos modificar la definición original de final="restriction" como sigue:
<complexType name="Direccion" block="restriction"> <sequence> <element name="nombre" type="string"/> <element name="calle" type="string"/> <element name="ciudad" type="string"/> </sequence> </complexType>
El valor restriction del
atributo block
previene que haya derivaciones por restricción que
reemplacen a Direccion en una instancia. Sin
embargo, no prevendría el que direccionEEUU y
direccionUK reemplazaran a Direccion
porque fueron derivadas por extensión. La
prevención de todo tipo de derivaciones, o de derivaciones
por extensión, se indica con los valores #all
y extension respectivamente. Como con final, existe un atributo opcional
blockDefault
en el elemento schema
cuyo valor puede ser uno de los valores permitidos para el
atributo block. El
efecto de especifcar el atributo blockDefault es equivalente
a especificar un atributo block para cada definición
de tipo y declaración de elemento del esquema.
La aplicación de pedidos y
facturación puede generar informes ad-hoc que resumen
qué cantidad de cada tipo de producto ha sido facturada
para cada región. Un ejemplo de ese tipo de informe, uno
que cubre el último trimestre de 1999, se muestra en
4Q99.xml.
Nótese que en esta sección se utilizan elementos calificados en el esquema, y , dentro de lo posible, espacios de nombres por defecto en las instancias.
<informePedidos xmlns="http://www.example.com/Report" periodo="P3M" finPeriodo="1999-12-31"> <regiones> <zip codigo="95819"> <producto numero="872-AA" cantidad="1"/> <producto numero="926-AA" cantidad="1"/> <producto numero="833-AA" cantidad="1"/> <producto numero="455-BX" cantidad="1"/> </zip> <zip codigo="63143"> <producto numero="455-BX" cantidad="4"/> </zip> </regiones> <productos> <producto numero="872-AA">Cortacésped</part> <producto numero="926-AA">Monitor de Bebés</part> <producto numero="833-AA">Collar de Lapis</part> <producto numero="455-BX">Estanterías Robustas</part> </productos> </informePedidos>
El informe lista, por número y cantidad, los productos
facturados a diferentes códigos de calles, y proporciona
una descripción de cada producto mencionado. Al resumir lo
datos de facturación, la intención del informe es
clara y los datos no son ambiguos porque existe un cierto
número de restricciones de uso. Por ejemplo, cada
código de calle aparece sólo una vez
(restricción de unicidad). De manera similar, la
descripción de cada producto facturado aparece una sola
vez aunque los productos pueden ser facturados a varios
códigos postales (restricción referencial),
véase por ejemplo el producto número
455-BX. En las secciones siguientes, veremos como
especificar estas constantes utilizando el Esquema XML.
<schema targetNamespace="http://www.example.com/Report"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:r="http://www.example.com/Report"
xmlns:xipo="http://www.example.com/IPO"
elementFormDefault="qualified">
<!-- para SKU -->
<import namespace="http://www.example.com/IPO"/>
<annotation>
<documentation xml:lang="es">
Esquema para Informes para Example.com
Copyright 2000 Example.com. Todos los derechos reservados.
</documentation>
</annotation>
<element name="informePedidos">
<complexType>
<sequence>
<element name="regiones" type="r:TipoRegion">
<keyref name="cualquiera2" refer="r:pNumClave">
<selector xpath="r:zip/r:producto"/>
<field xpath="@numero"/>
</keyref>
</element>
<element name="productos" type="r:TipoProducto"/>
</sequence>
<attribute name="periodo" type="duration"/>
<attribute name="finPeriodo" type="date"/>
</complexType>
<unique name="cualquiera1">
<selector xpath="r:regiones/r:zip"/>
<field xpath="@codigo"/>
</unique>
<key name="pNumClave">
<selector xpath="r:productos/r:producto"/>
<field xpath="@numero"/>
</key>
</element>
<complexType name="TipoRegion">
<sequence>
<element name="zip" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="producto" maxOccurs="unbounded">
<complexType>
<complexContent>
<restriction base="anyType">
<attribute name="numero" type="xipo:SKU"/>
<attribute name="cantidad" type="positiveInteger"/>
</restriction>
</complexContent>
</complexType>
</element>
</sequence>
<attribute name="codigo" type="positiveInteger"/>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="TipoProducto">
<sequence>
<element name="producto" maxOccurs="unbounded">
<complexType>
<simpleContent>
<extension base="string">
<attribute name="numero" type="xipo:SKU"/>
</extension>
</simpleContent>
</complexType>
</element>
</sequence>
</complexType>
</schema>
El Esquema XML nos facilita el indicar que
cualquier valor de un atributo o elemento sea único en un
cierto ámbito. Para indicar que un valor de un "campo" de
un atributo o elemento debe ser único, utilizamos el
elemento unique [único] primero para
"seleccionar" un conjunto de elementos, y después para
identificar el "campo" del atributo o elemento relativo a cada
elemento seleccionado y que tiene que ser único dentro del
ámbito del conjunto de elementos seleccionados. En el caso
de nuestro esquema para informes, report.xsd, el atributo xpath del elemento selector contiene una
expresión XPath, regiones/zip, que selecciona
una lista de todos los elementos zip en una
instancia de informe. Del mismo modo, el atributo xpath del elemento selector contiene una segunda
expresión XPath, @codigo, que indica que los
valores de los atributos codigo, de esos elementos
deben ser únicos. Nótese que las expresiones XPath
limitan el ámbito de lo que debe ser único. El
informe debe contener otro atributo codigo, pero sus
valores no tienen porqué ser únicos porque cae
fuera del ámbito definido por las expresiones XPath.
También hay que resaltar que las expresiones XPath que se
pueden utilizar en el atributo xpath están limitadas a un
subconjunto del lenguaje XPath completo definido en XML Path Language
1.0.
También podemos indicar combinaciones de campos que
deben ser únicas. Para ilustrarlo, supongamos que podemos
relajar la restricción de que los códigos zip
puedan ser listados sólo una vez, aunque aún
deseamos mantener la restricción de que un producto
cualquiera sea listado una sola vez dentro de un código
dado. Podemos lograr tal restricción especificando que la
combinación del código zip y del número de
producto sea única. Del documento del informe, 4Q99.xml, los valores combinados de
codigo y numero serían:
{95819 872-AA}, {95819 926-AA},
{95819 833-AA}, {95819 455-BX}, y
{63143 455-BX}. Claramente, estas combinaciones no
distinguen entre combinaciones de codigo y
numero zip derivadas de una o varias listas para un
código zip particular, pero las combinaciones
representarían de forma no ambigua un producto listado
más de una vez para un único zip. En otras
palabras, un procesador de esquemas podría detectar
violaciones de la restricción de unicidad.
Para definir combinaciones de valores, simplemente
añadimos elementos field [campo] para identificar los valores
involucrados. así, para añadir el número de
producto a nuestra definición existente, añadimos
un nuevo elemento field
cuyo atributo xpath
que vale, producto/@numero, identifica el atributo
numero de los elementos producto que
son hijos de los elementos zip identificados por
regiones/zip:
<unique name="cualquiera1"> <selector xpath="r:regiones/r:zip"/> <field xpath="@codigo"/> <field xpath="r:producto/@numero"/> </unique>
En el informe trimestral de 1999 la
descripción de cada producto sólo aparece una vez.
Podemos imponer esta restricción utilizando unique, sin embargo, también
queremos asegurar que cualquier elemento cantidad-producto
listado bajo un código zip tiene una descripción de
producto correspondiente. Imponemos la restricción
utilizando los elementos key [clave] y keyref [referencia clave]. El esquema de informes
report.xsd, muestra que
las construcciones key y
keyref son aplicadas
utilizando casi la misma sintaxis que unique. Los elementos clave se
aplican al valor del atributo numero de los
elementos producto que son hijos del elemento
productos. Esta declaración de
numero como clave significa que su valor debe ser
único y no puede ser igualado a nil (es decir, no es
anulable), y el nombre asociado con la clave,
pNumClave, hace que ésta sea referenciable
desde cualquier otro sitio.
Para asegurar que los elementos cantidad-producto tienen sus
correspondientes descripciones de producto, decimos que el
atributo numero (
<field>@numero</field>) de esos
elementos
(<selector>zip/producto</selector>) debe
referenciar la clave pNumClave. Esta
declaración de numero como una
keyref no significa que su valor deba ser
único, pero significa que debe existir una
pNumClave con el mismo valor.
Como te habrás imaginado por analogía con
unique, es posible
definir combinaciones de valores key y keyref. utilizando este mecanismo,
podemos ir más allá del simple requerimiento de que
los números de los productos sean iguales, y definir una
combinación de valores que debe ser igual. Tales valores
pueden ser de combinaciones de múltiples tipos de valores
combinaciones de valores (string, integer, date, etc.), comprobando que el orden y tipo
de la referencia del elemento field es la misma en las definiciones
de key y keyref.
XML
1.0 proporciona un mecanismo de unicidad utilizando el
atributo ID que es asociado con los atributos IDREF y IDREFS.
Este mecanismo también está presente en el Esquema
XML a través de los tipos simples ID, IDREF, y
IDREFS que pueden ser
utilizados para declarar atributos del estilo de los de XML 1.0.
El Esquema XML también introduce mecanismo nuevos que son
más flexibles y potentes. Por ejemplo, los mecanismos del
Esquema XML pueden ser aplicados a cualquier contenido de
elemento o atributo, sin importar su tipo. Por contra, ID es un
tipo de atributo y por tanto no puede ser aplicado a
atributos, elementos o a su contenido. Más aún, el
Esquema facilita la posibilidad de especificar el ámbito
dentro del cual se aplica la unicidad mientras que el
ámbito de un ID es fijado a todo el documento. Finalmente,
el Esquema facilita la posibilidad de crear keys o una keyref a partir de combinaciones del
contenido de elementos y atributos mientras que el ID no tiene
esta posibilidad.
El esquema de los informes, report.xsd, hace uso del tipo simple
xipo:SKU que está definido en otro esquema, y
en otro espacio de nombres. Recordemos que hemos utilizado
include así
que el esquema de ipo.xsd
podría hacer uso de las definiciones y declaraciones de
address.xsd. No podemos
usar include
aquí porque sólo puede incluir declaraciones y
definiciones de un esquema con el mismo espacio de nombres que el
esquema en el que lo queremos incluir. Por tanto, el elemento
include no identifica
un espacio de nombres (aunque requiere un schemaLocation). El
mecanismo de importación que describimos en esta
sección es un mecanismo importante que permite que
componentes de esquemas procedentes de diferentes partes puedan
ser utilizados conjuntamente, y por tanto posibilita la
validación de esquemas con contenido definido en
múltiples espacios de nombres.
Para importar el tipo SKU y
utilizarlo en el esquema de los informes, identificamos el
esquema en el que SKU está definido, y
asociamos ese espacio de nombres con un prefijo para usarlo en el
esquema de los informes. Concretamente, utilizamos el elemento
import para
identificar el espacio de nombres de SKU,
http://www.example.com/IPO, y asociamos el espacio
de nombres con el prefijo xipo utilizando una
declaración de tipo estándar. El tipo simple
SKU, definido en el espacio de nombres
http://www.example.com/IPO, entonces puede ser
referenciado como xipo:SKU en cualquiera de las
definiciones y declaraciones del esquema.
En nuestro ejemplo, importamos un tipo simple de un espacio de
nombres externo, y lo utilizamos para declarar atributos. De
hecho el Esquema XML permite importar múltiples
componentes de esquema, de múltiples espacios de nombres,
y pueden ser referenciados tanto por definiciones como por
declaraciones. Por ejemplo, en report.xsd, podríamos
además reutilizar el elemento comentario
declarado en ipo.xsd
referenciando ese elemento en una declaración:
<element ref="xipo:comentario"/>
Nótese de todas formas, que no podemos reutilizar el
elemento enviarA de po.xsd, y que lo siguiente no es legal
porque sólo pueden importarse componentes
globales de un esquema:
<element ref="xipo:enviarA"/>
En ipo.xsd,
comentario es declarado como un elemento global, en
otras palabras es declarado como un elemento del schema. Por contra,
enviarA es declarado localmente, en otras palabras
es un elemento declarado dentro de una definición de tipo
complejo, específicamente el tipo
TipoHojaPedido.
Los tipos complejos también pueden importarse, y pueden
ser utilizados como los tipos base para derivar tipos nuevos.
Sólo se pueden importar tipos complejos con nombre; los
tipos locales o definidos de forma anónima no pueden ser
importados. Supongamos que queremos incluir en nuestros informes
el nombre de un analista, junto con su información de
contacto. Podemos reutilizar el tipo complejo (definido
globalmente) direccionEEUU de address.xsd, y extenderlo para definir
un tipo nuevo llamado Analista añadiendo los
elementos nuevos telefono y email:
<complexType name="Analista">
<complexContent>
<extension base="xipo:direccionEEUU">
<sequence>
<element name="telefono" type="string"/>
<element name="email" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
Para utilizar este tipo nuevo declaramos un elemento llamado
analista como parte de la declaración del
elemento informePedidos (no se muestran las
declaraciones) en el esquema de los informes. Entonces, la
siguiente instancia de documento conformaría con el
esquema de informes modificado:
<informePedidos
xmlns="http://www.example.com/Report"
periodo="P3M" finPeriodo="1999-12-31">
<!-- se han omitido regiones y números de productos -->
<analista>
<nombre>Wendy Uhro</nombre>
<calle>10 Corporate Towers</calle>
<ciudad>San Jose</ciudad>
<estado>CA</estado>
<zip>95113</zip>
<telefono>408-271-3366</telefono>
<email>uhro@example.com</email>
</analista>
</informePedidos>
Cuando los componentes del esquema son importados de
múltiples espacios de nombres, cada espacio de nombres
debe identificarse con un import separado. Los elementos
import por si mismos
deben aparecer como el primero de los hijos del elemento schema. Es más, cada
espacio de nombres debe estar asociado con un prefijo, utilizar
una declaración de espacio de nombres de tipo
estándar, y que el prefijo sea utilizado para calificar
referencias realizadas a los componentes pertenecientes a ese
espacio de nombres. Finalmente, los elementos import contienen opcionalmente un
atributo schemaLocation para ayudar
a localizar los recursos asociados con los espacios de nombres.
Discutiremos el atributo schemaLocation con
más detalle en una sección posterior.
A medida que el uso de los esquemas XML se vaya extendiendo, los autores de esquemas querrán ir creando tipos simples y complejos que puedan ser compartidos y utilizados como ladrillos para la construcción de nuevos esquemas. Los Esquemas XML ya proporcionan tipos que juegan este papel, en particular, los tipos descritos en el Apéndice de Tipos Simples y en una biblioteca de tipos preliminar.
Los autores de esquemas querrán indudablemente crear sus propias bibliotecas de tipos para representar monedas, unidades de medida, direcciones de negocios, y demás. Cada biblioteca debería de consistir de un esquema que contenga una o más definiciones, por ejemplo, un esquema que contiene un tipo de moneda:
<schema targetNamespace="http://www.example.com/Currency"
xmlns:c="http://www.example.com/Currency"
xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<documentation xml:lang="es">
Definición del tipo Moneda basado en la ISO 4217
</documentation>
</annotation>
<complexType name="Moneda">
<simpleContent>
<extension base="decimal">
<attribute name="nombre">
<simpleType>
<restriction base="string">
<enumeration value="AED">
<annotation>
<documentation xml:lang="es">
Emiratos Árabes Unidos: Dirham (1 Dirham = 100 Fils)
</documentation>
</annotation>
</enumeration>
<enumeration value="AFA">
<annotation>
<documentation xml:lang="es">
Afganistán: Afghani (1 Afghani = 100 Puls)
</documentation>
</annotation>
</enumeration>
<enumeration value="ALL">
<annotation>
<documentation xml:lang="es">
Albania, Lek (1 Lek = 100 Qindarka)
</documentation>
</annotation>
</enumeration>
<!-- y otras monedas -->
</restriction>
</simpleType>
</attribute>
</extension>
</simpleContent>
</complexType>
</schema>
Un ejemplo de aparición de un elemento de este tipo en una instancia:
<convertirDe nombre="AFA">199.37</convertirDe>
Una vez que hemos definido el tipo moneda, podemos hacer que
esté disponible para ser usado por otros esquemas mediante
el mecanismo import
recientemente descrito.
En secciones anteriores hemos visto varios mecanismos para extender el modelo de contenido de tipos complejos. Por ejemplo, un modelo de contenido mixto puede contener datos de caracteres además de elementos, y por ejemplo, un modelo de contenido puede contener elementos cuyos tipos son importados de espacios de nombres externos. Sin embargo, estos mecanismos proporcionan un control muy amplio y muy pequeño respectivamente. El propósito de esta sección es describir un mecanismo flexible que permita que los modelos de contenido sean extendidos por cualquier elemento o atributo que pertenezca a un espacio de nombres especificado.
Para ilustrarlo, consideremos una versión del informe
trimestral, 4Q99html.xml, en la que hemos incluido
una representación HTML de los datos XML de productos. El
contenido HTML aparece como el contenido de el elemento
ejemploHTML, y el espacio de nombres por defecto es
cambiado en el elemento HTML más externo
(table) por lo que todos los elementos pertenecen al
espacio de nombres HTML,
http://www.w3.org/1999/xhtml:
<informePedidos
xmlns="http://www.example.com/Report"
periodo="P3M" finPeriodo="1999-12-31">
<regiones>
<!-- ventas por piezas listadas por código zip, datos de 4Q99.xml -->
</regiones>
<productos>
<!-- descripciones de productos de 4Q99.xml -->
</productos>
<ejemploHTML>
<table xmlns="http://www.w3.org/1999/xhtml"
border="0" width="100%">
<tr>
<th align="left">Código Zip</th>
<th align="left">Número de Producto</th>
<th align="left">Cantidad</th>
</tr>
<tr><td>95819</td><td> </td><td> </td></tr>
<tr><td> </td><td>872-AA</td><td>1</td></tr>
<tr><td> </td><td>926-AA</td><td>1</td></tr>
<tr><td> </td><td>833-AA</td><td>1</td></tr>
<tr><td> </td><td>455-BX</td><td>1</td></tr>
<tr><td>63143</td><td> </td><td> </td></tr>
<tr><td> </td><td>455-BX</td><td>4</td></tr>
</table>
</ejemploHTML>
</informePedidos>
Para permitir la aparición de HTML
en el documento instancia hemos modificado el esquema del informe
declarando un elemento nuevo ejemploHTML cuyo
contenido es definido por el elemento any. En general, un elemento any especifica que cualquier XML
bien formado es permisible en el modelo de contenido de un tipo.
En el ejemplo, requerimos que el XML pertenezca al espacio de
nombres http://www.w3.org/1999/xhtml, en otras
palabras, debe ser HTML. El ejemplo también requiere que
haya al menos un elemento presente para este espacio de nombres,
como se indica en los valores de minOccurs y maxOccurs:
<element name="informePedido">
<complexType>
<sequence>
<element name="regiones" type="r:TipoRegiones"/>
<element name="productos" type="r:TipoProductos"/>
<element name="ejemploHTML">
<complexType>
<sequence>
<any namespace="http://www.w3.org/1999/xhtml"
minOccurs="1" maxOccurs="unbounded"
processContents="skip"/>
</sequence>
</complexType>
</element>
</sequence>
<attribute name="periodo" type="duration"/>
<attribute name="finPeriodo" type="date"/>
</complexType>
</element>
La modificación permite que
aparezca algo de contenido XML bien formado peteneciente al
espacio de nombres http://www.w3.org/1999/xhtml
dentro del elemento ejemploHTML. Por consiguiente
4Q99html.xml está
permitido porque hay un elemento, el cual (y sus hijos)
está bien formado, el elemento aparece dentro del elemento
apropiado (ejemploHTML), y el documento instancia
asegura que el elemento y su contenido pertenecen al espacio de
nombres requerido. Sin embargo, el HTML podría no ser
realmente válido porque no hay nada en 4Q99html.xml por si mismo que pueda
proporcionar esa garantía. Si se requiere tal
garantía, el valor del atributo processContents [proceso de contenidos] debería
ser igual a strict [estricto] (el valor por defecto). En este
caso, el procesador de XML está obligado a obtener el
esquema asociado con el espacio de nombres requerido, y validar
el HTML que aparece dentro del elemento
ejemploHTML.
En otro ejemplo, definimos un tipo
texto que es similar al tipo text [texto] definido en la biblioteca
de tipos preliminar del Esquema XML (ver también la Sección 5.4.1), y es apropiado para texto
internacionalizado legible por humanos. El tipo text permite una
mezcla sin restricciones de caracteres y elementos de cualquier
espacio de nombres, por ejemplo anotaciones Ruby con un atributo
xml:lang opcional. El valor lax del
atributo processContents instruye
al procesador XML para que valide el contenido de elemento en
base a lo que puede-hacer: validará elementos y atributos
para los que puede obtener información del esquema, pero
no señalará errores para los que no puede
obtenerla.
<xsd:complexType name="texto">
<xsd:complexContent mixed="true">
<xsd:restriction base="xsd:anyType">
<xsd:sequence>
<xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute ref="xml:lang"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
Los espacios de nombres pueden ser
utilizados para permitir y prohibir contenido de elementos de
varias formas dependiendo del valor del atributo namespace, como se muestra en
la Tabla 4:
Además del elemento any que facilita la inclusión de
elementos de acuerdo con los espacios de nombres respectivos,
existe un elemento correspondiente llamado anyAttribute [cualquierAtributo] que posibilita la
aparición de atributos en elementos. Por ejemplo, podemos
permitir que cualquier atributo HTML aparezca como parte del
elemento ejemploHTML añadiendo anyAttribute a su
declaración:
<element name="ejemploHTML">
<complexType>
<sequence>
<any namespace="http://www.w3.org/1999/xhtml"
minOccurs="1" maxOccurs="unbounded"
processContents="skip"/>
</sequence>
<anyAttribute namespace="http://www.w3.org/1999/xhtml"/>
</complexType>
</element>
Esta declaración permite que un atributo HTML, pongamos
href, aparezca en el elemento
ejemploHTML. Por ejemplo:
....
<ejemploHTML xmlns:h="http://www.w3.org/1999/xhtml"
h:href="http://www.example.com/reports/4Q99.html">
<!-- marcado HTML aquí -->
</ejemploHTML>
....
El atributo namespace en un elemento
anyAttribute
puede tener un valor igual a cualquiera de los valores listados
en la Tabla 4 para el elemento any, y anyAttribute puede ser
especificado con un atributo processContents. A
diferencia de un elemento any, anyAttribute no puede
restringir el número de atributos que puede aparecer en un
elemento.
El Esquema XML utiliza los atributos schemaLocation y xsi:schemaLocation en
tres circunstancias:
1. En un documento instancia, el atributo
xsi:schemaLocation
proporciona indicaciones del autor para el procesador en cuanto a
la localización de documentos de esquema. El autor
garantiza que estos documentos de esquemas son relevantes para
comprobar la validez del contenido del documento, en base a cada
uno de los espacios de nombres. Por ejemplo, podemos indicar la
localización del esquema de Informes a un procesador del
Informe Trimestral:
<informePedidos xmlns="http://www.example.com/Report" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/Report http://www.example.com/Report.xsd" periodo="P3M" finPeriodo="1999-12-31"> <!-- etc. --> </informePedidos>
El atributo schemaLocation contiene
parejas de valores. El primer miembro de cada par es el espacio
de nombres para el que el segundo miembro es la indicación
de dónde se encuentra el documento del esquema adecuado.
La presencia de estas indicaciones no obliga al procesador a
utilizar los esquemas citados, y el procesador es libre de
utilizar otros esquemas obtenidos por cualquier otro medio
apropiado, o de no usar ningún esquema.
No es obligatorio que un esquema tenga un espacio de nombres
(ver Sección 3.4) y por eso
tenemos un atributo noNamespaceSchemaLocation
que es utilizado para proporcionar indicaciones para la
localización de esquemas en los documentos que no tienen
un espacio de nombres asociado.
2. En un esquema, el elemento include tiene un atributo schemaLocation
obligatorio, y contiene una referencia URI que debe identificar a
un esquema. El efecto es componer un esquema final efectivo
mediante la mezcla de las declaraciones y definiciones de los
esquemas que se incluyen y del esquema incluye a éstos.
Por ejemplo, en la Sección 4, las
definiciones de los tipos direccion,
direccionEEUU, direccionUK,
estadoEEUU (junto con las declaraciones de sus
elementos y atributos locales) de address.xsd fueron añadidas a
las declaraciones de los elementos de hojaPedido y
comentario, y las definiciones de tipo de
TipoHojaPedido, Elementos y
SKU (junto con las declaraciones de sus elementos y
atributos locales) de ipo.xsd
para crear un único esquema.
3. También en un esquema, el elemento import tiene unos atributos namespace y schemaLocation. Si
aparecen, el atributo schemaLocation es
entendido en un modo paralelo a la interpretación de
xsi:schemaLocation en
(1). Específicamente, proporciona una indicación
del autor a un procesador en cuanto a la localización del
esquema que el autor garantiza que proporciona los componentes
necesarios para el espacio de nombres identificado por el
atributo namespace. Para importar
componentes que no están en ningún espacio de
nombres, el elemento import se usa sin un atributo
namespace (y con
o sin un atributo schemaLocation). Las
referencias a elementos importados de esta manera se hacen sin
calificar.
Recuerda que el schemaLocation es
sólo una indicación y que algunos procesadores y
aplicaciones tendrán razones para no utilizarlo. Por
ejemplo, un editor HTML puede tener un esquema HTML
predefinido.
Un documento instancia puede ser procesado contra un esquema para verificar que las reglas especificadas en el esquema son cumplidas por la instancia. Típicamente, tal proceso hace dos cosas, (1) comprueba la corcondancia con las reglas, un proceso llamado validación de esquema, y (2) añade información suplementaria que no está inmediatamente presente en la instancia, como tipos y valores por defecto, llamados contribuciones al conjunto de información.
El autor de un documento instancia, tal como una hoja de
pedido concreta, puede especificar, en la misma instancia, que
conforme (concuerde) con las reglas de un esquema particular. El
autor hace esto utilizando el atributo schemaLocation discutido
anteriormente. Pero sin importar si un atributo schemaLocation está
o no presente, una aplicación es libre de procesar el
documento contra cualquier esquema. Por ejemplo, una
aplicación de pedidos pude tener la política de
utilizar siempre el mismo esquema determinado de hoja de pedido,
a pesar de cualquier valor de schemaLocation.
La comprobación de concordancia puede ser pensada como un proceso en tres pasos, primero se comprueba que el elemento raíz del documento instancia tiene los contenidos adecuados, entonces se comprueba que cada subelemento conforma con su descripción en el esquema, y así hasta que el documento completo se verifica. Los procesadores deben informar de qué tipo de comprobaciones han llevado a cabo.
Para comprobar la concordancia de un elemento, el procesador
primero localiza la declaración del elemento targetNamespace en
el esquema, y entonces comprueba que el atributo en el esquema
coincide con el de URI de espacio de nombres actual del elemento.
Alternativamente, se puede determinar que el esquema no tiene un
atributo targetNamespace y que el
elemento de la instancia no está calificado.
Suponiendo que los espacios de nombres concuerden, el
procesador entonces examina el tipo del elemento, ya sea el dado
por la declaración en el esquema o el del atributo
xsi:type en la
instancia. Si se da este último caso, el tipo de la
instancia debe ser de un tipo que pueda ser sustituido por el
dado en el esquema, lo que es permitido se controla mediante el
atributo block en la
declaración del elemento. En ese mismo momento, se aplican
los valores por defecto y otras contribuciones al conjunto de la
información.
A continuación el procesador comprueba los contenidos y
los atributos propios del elemento, comparando estos valores con
los permitidos por el tipo del elemento. Por ejemplo,
consideremos un elemento enviarA tal como el de la
Sección 2.1, el procesador
comprueba lo que es permitido para una direccion,
porque ese es el tipo del elemento enviarA.
Si el elemento tiene un tipo simple, el procesador verifica que el elemento no tiene atributos ni contiene elementos, y que su contenido de tipos carácter coincide con las reglas para el tipo simple. Esto, en ocasiones, obliga a la comprobación de la secuencia de caracteres contra expresiones regulares o enumeraciones, y a veces a comprobar que la secuencia de caracteres representa un valor dentro de un rango permitido.
Si el elemento tiene tipo complejo, entonces el procesador comprueba que los atributos requeridos están presentes y que sus valores concuerdan con los requerimientos de sus tipos simples. También comprueba que todos los subelementos requeridos estén presentes, y que la secuencia de elementos (y de cualquier texto mezclado) coincide con el modelo de contenido declarado para el tipo complejo. En cuanto a los subelementos, los esquemas pueden o bien requerir coincidencia exacta de nombres, permitir sustitución por un elemento equivalente o permitir sustitución por cualquier elemento permitido por una partícula 'any'.
A no ser que el esquema lo indique de manera contraria (como puede hacerlo mediante partículas 'any'), la comprobación de concordancia procede entonces con el siguiente nivel más profundo inspeccionando cada elemento uno a uno, repitiendo el proceso descrito arriba.
Mucha gente ha contribuido con sus ideas, material y comentarios que han mejorado este documento. En particular, el editor quiere reconocer las contribuciones de David Beech, Paul Biron, Don Box, Allen Brown, David Cleary, Dan Connolly, Roger Costello, Martin Dürst, Martin Gudgin, Dave Hollander, Joe Kesselman, John McCarthy, Andrew Layman, Eve Maler, Ashok Malhotra, Noah Mendelsohn, Michael Sperberg-McQueen, Henry Thompson, Misha Wolf, y Priscilla Walmsley por validar los ejemplos.
Los valores legales para cada tipo simple pueden ser restringidos por la aplicación de una o más propiedades. Las Tablas B1.a y B1.b listan todos los tipos simples y todas las propiedades aplicables a cada uno de los tipos, que vienen predefinidas en el Esquema XML. Los nombres de los tipos simples y sus propiedades están enlazados a las tablas con sus correspondientes descripciones en Esquema XML Parte 2: Tipos de Datos
| Tabla B1.a. Tipos Simples y Propiedades Aplicables | ||||||
|---|---|---|---|---|---|---|
| Tipos Simples | Propiedades | |||||
| length [longitud] |
minLength [longitud mínima] |
maxLength [longitud máxima] |
pattern [patrón] |
enumeration [enumeración] |
whiteSpace [espacios en blanco] |
|
| string | y | y | y | y | y | y |
| normalizedString | y | y | y | y | y | y |
| token | y | y | y | y | y | y |
| byte | y | y | y | |||
| unsignedByte | y | y | y | |||
| base64Binary | y | y | y | y | y | y |
| hexBinary | y | y | y | y | y | y |
| integer | y | y | y | |||
| positiveInteger | y | y | y | |||
| negativeInteger | y | y | y | |||
| nonNegativeInteger | y | y | y | |||
| nonPositiveInteger | y | y | y | |||
| int | y | y | y | |||
| unsignedInt | y | y | y | |||
| long | y | y | y | |||
| unsignedLong | y | y | y | |||
| short | y | y | y | |||
| unsignedShort | y | y | y | |||
| decimal | y | y | y | |||
| float | y | y | y | |||
| double | y | y | y | |||
| boolean | y | y | ||||
| time | y | y | y | |||
| dateTime | y | y | y | |||
| duration | y | y | y | |||
| date | y | y | y | |||
| gMonth | y | y | y | |||
| gYear | y | y | y | |||
| gYearMonth | y | y | y | |||
| gDay | y | y | y | |||
| gMonthDay | y | y | y | |||
| Name | y | y | y | y | y | y |
| QName | y | y | y | y | y | y |
| NCName | y | y | y | y | y | y |
| anyURI | y | y | y | y | y | y |
| language | y | y | y | y | y | y |
| ID | y | y | y | y | y | y |
| IDREF | y | y | y | y | y | y |
| IDREFS | y | y | y | y | y | |
| ENTITY | y | y | y | y | y | y |
| ENTITIES | y | y | y | y | y | |
| NOTATION | y | y | y | y | y | y |
| NMTOKEN | y | y | y | y | y | y |
| NMTOKENS | y | y | y | y | y | |
Las propiedades listadas en la Tabla B1.b se aplican sólo a tipos simples ordenados. No todos los simples están ordenados por lo que B1.b no lista todos los tipos simples.
| Tabla B1.b. Tipos Simples y Propiedades Aplicables | ||||||||
|---|---|---|---|---|---|---|---|---|
| Tipos Simples | Propiedades | |||||||
|
max Inclusive [máximo inclusive] |
max Exclusive [máximo exclusive] |
min Inclusive [mínimo inclusive] |
min Exclusive [mínimo exclusive] |
totalDigits [dígitos totales] |
fractionDigits [dígitos de fracción] |
|||
| byte | y | y | y | y | y | y | ||
| unsignedByte | y | y | y | y | y | y | ||
| integer | y | y | y | y | y | y | ||
| positiveInteger | y | y | y | y | y | y | ||
| negativeInteger | y | y | y | y | y | y | ||
| nonNegativeInteger | y | y | y | y | y | y | ||
| nonPositiveInteger | y | y | y | y | y | y | ||
| int | y | y | y | y | y | y | ||
| unsignedInt | y | y | y | y | y | y | ||
| long | y | y | y | y | y | y | ||
| unsignedLong | y | y | y | y | y | y | ||
| short | y | y | y | y | y | y | ||
| unsignedShort | y | y | y | y | y | y | ||
| decimal | y | y | y | y | y | y | ||
| float | y | y | y | y | ||||
| double | y | y | y | y | ||||
| time | y | y | y | y | ||||
| dateTime | y | y | y | y | ||||
| duration | y | y | y | y | ||||
| date | y | y | y | y | ||||
| gMonth | y | y | y | y | ||||
| gYear | y | y | y | y | ||||
| gYearMonth | y | y | y | y | ||||
| gDay | y | y | y | y | ||||
| gMonthDay | y | y | y | y | ||||
XML 1.0 proporciona varios tipos de entidades que son fragmentos de contenidos a los que se le da un nombre y que pueden ser utilizados en DTD's (entidades parámetro) y en documentos instancia. En la Sección 2.7, explicamos cómo los grupos con nombre mimetizan a las entidades parámetro. En esta sección mostramos cómo las entidades pueden ser declaradas en los esquemas.
Supongamos que queremos declarar y usar una entidad en un documento, y que ese documento también esté restringido por un esquema. Por ejemplo:
<?xml version="1.0" ?>
<!DOCTYPE hojaPedido [
<!ENTITY eacute "é">
]>
<hojaPedido xmlns="http://www.example.com/PO1"
fechaPedido="1999-10-20>
<!-- etc. -->
<ciudad>Montréal</ciudad>
<!-- etc. -->
</hojaPedido>
Aquí, declaramos una entidad llamada
eacute como parte de un subconjunto (DTD) interno, y
referenciamos esta entidad en el contenido del elemento
ciudad. Nótese que cuando esta instancia es
procesada, la entidad será dereferenciada antes de que
tenga lugar la validación del esquema. En otras palabras,
un procesador del esquema determinará la validad del
elemento ciudad utilizando
Montréal como el valor del elemento.
Podemos lograr un efecto similar pero no idéntico declarando un elemento en un esquema, y utilizando un contenido apropiado para el mismo:
<xsd:element name="eacute" type="xsd:token" fixed="é"/>
Y este elemento puede ser utilizado en un documento instancia:
<?xml version="1.0" ?>
<hojaPedido xmlns="http://www.example.com/PO1"
xmlns:c="http://www.example.com/characterElements"
fechaPedido="1999-10-20>
<!-- etc. -->
<ciudad>Montr<c:eacute/>al</ciudad>
<!-- etc. -->
</hojaPedido>
En este caso, un procesador del esquema procesará dos
elementos, un elemento ciudad, y un elemento
eacute para los contenidos de los que el procesador
obtendrá el carácter simple é.
El elemento extra complicará la comparación de
cadenas; las dos formas dadas del nombre "Montréal" en los
dos ejemplos anteriores no coincidirán utilizando
técnicas normales de comparación de cadenas.
La propiedad pattern del Esquema XML utiliza un
lenguaje de expresiones regulares que soporta Unicode.
Está totalmente descrito en Esquema
Parte 2. El lenguaje es similar al lenguaje de expresiones
regulares utilizado en el Lenguaje de
Programación Perl, aunque las expresiones son
comparadas con representaciones totalmente léxicas en vez
de con representaciones enfocadas léxicamente al usuario
como línea y párrafo. Por esta razón, el
lenguaje de expresiones no contiene los metacaracteres ^ y $,
aunque ^ se utiliza para expresar excepción. p.e.
[^0-9]x.
| Tabla D1. Ejemplos de Expresiones Regulares | |
|---|---|
| Expresión | Coincidencia(s) |
| Capitulo \d | Capitulo 0, Capitulo 1, Capitulo 2 .... |
| Capitulo\s\d | Capitulo seguido de un único espacio en blanco (espacio, tabulador, nueva línea, etc.), seguido de un único dígito |
| Capitulo\s\w | Capitulo seguido de un único espacio en blanco (espacio, tabulador, nueva línea, etc.), seguido de un carácter (Letra o Dígito XML 1.0t) |
| Espanñola | Española |
| \p{Lu} | cualquier letra mayúscula, el valor de \p{} (p.e. "Lu") es definido por Unicode |
| \p{IsGreek} | cualquier carácter Griego, la construcción 'Is' puede ser aplicada a cualquier nombre elemento nombre (p.e. "Greek") según definido por Unicode |
| \P{IsGreek} | cualquier carácter No Griego, la construcción 'Is' puede ser aplicada a cualquier nombre elemento nombre (p.e. "Greek") según definido por Unicode |
| a*x | x, ax, aax, aaax .... |
| a?x | ax, x |
| a+x | ax, aax, aaax .... |
| (a|b)+x | ax, bx, aax, abx, bax, bbx, aaax, aabx, abax, abbx, baax, babx, bbax, bbbx, aaaax .... |
| [abcde]x | ax, bx, cx, dx, ex |
| [a-e]x | ax, bx, cx, dx, ex |
| [-ae]x | -x, ax, ex |
| [ae-]x | ax, ex, -x |
| [^0-9]x | cualquier carácter no-dígito seguido del carácter x |
| \Dx | cualquier carácter no-dígito seguido del carácter x |
| .x | cualquier carácter seguido del carácter x |
| .*abc.* | 1x2abc, abc1x2, z3456abchooray .... |
| ab{2}x | abbx |
| ab{2,4}x | abbx, abbbx, abbbbx |
| ab{2,}x | abbx, abbbx, abbbbx .... |
| (ab){2}x | ababx |
Elementos del Esquema XML. Cada nombre de elemento está enlazado a su descripción en las partes de Estructuras o Tipos de Datos de la especificación del Esquema XML. Los nombres de elementos están seguidos de uno o más enlaces a ejemplos (identificados por número de sección) en este documento de Fundamentos.
all: 2.7
annotation: 2.6
any: 5.5
anyAttribute: 5.5
appInfo: 2.6
attribute: 2.2
attributeGroup: 2.8
choice: 2.7
complexContent: 2.5.3
complexType: 2.2
documentation: 2.6
element: 2.2
enumeration: 2.3
extension: 2.5.1, 4.2
field: 5.1
group: 2.7
import: 5.4
include: 4.1
key: 5.2
keyref: 5.2
length: 2.3.1
list: 2.3.1
maxInclusive: 2.3
maxLength: 2.3.1
minInclusive: 2.3
minLength: 2.3.1
pattern: 2.3
redefine: 4.5
restriction: 2.3, 4.4
schema: 2.1
selector: 5.1
sequence: 2.7
simpleContent: 2.5.1
simpleType: 2.3
union: 2.3.2
unique: 5.1
Atributos del Esquema XML. Cada nombre de atributo está seguido de uno o más pares de referencias. Cada par de referencias consiste de enlace a un ejemplo en estos Fundamentos, además de un enlace a su descripción formal en las partes de Estructuras o Tipos de Datos de la especificación del Esquema XML.
abstract: declaración del elemento [
Estructuras], definición del tipo
complejo [
Estructuras]attributeFormDefault:
elemento schema [
Estructuras]base: definición del tipo simple [
Tipos de Datos], definición del tipo
complejo [
Estructuras]block: definición del tipo complejo [
Estructuras],blockDefault: elemento schema
[
Estructuras]default: declaración de atributo [
Estructuras],default: declaración del elemento [
Estructuras],elementFormDefault:
elemento schema [
Estructuras]final: definición del tipo complejo [
Estructuras]finalDefault: elemento schema
[
Estructuras]fixed: declaración de atributo [
Estructuras],fixed: declaración del elemento [
Estructuras]fixed: definición del tipo simple [Tipos
de Datos]form: declaración del elemento [
Estructuras], declaración de
atributo [
Estructuras]itemType: definición de tipo lista [
Tipos de Datos]memberTypes:
definición de tipo unión [
Tipos de Datos]maxOccurs: declaración del elemento [
Estructuras]minOccurs: declaración del elemento [
Estructuras]mixed:
definición del tipo complejo [
Estructuras]name: declaración del elemento [
Estructuras], declaración de
atributo [
Estructuras], definición del tipo
complejo [
Estructuras], definición del tipo
simple [
Tipos de Datos]namespace: elemento any
[
Estructuras], include
element [
Estructuras]noNamespaceSchemaLocation:
elemento instance [Estructuras]xsi:nil:element instance
[Estructuras]nillable: declaración del elemento [
Estructuras]processContents: elemento any
[
Estructuras], anyAttribute
element [
Estructuras]ref: declaración del elemento [
Estructuras]schemaLocation: especificación de include [
Estructuras], especificación de
redefine [
Estructuras], especificación de
import [
Estructuras]xsi:schemaLocation:
atributo instancia [
Estructuras]substitutionGroup: declaración del elemento [
Estructuras]targetNamespace: elemento schema [
Estructuras]type: declaración del elemento [
Estructuras], declaración de
atributo [
Estructuras]xsi:type: instance element [Estructuras]use: declaración de atributo [
Estructuras]xpath: selector & field
elements [
Estructuras]Los tipos simples del Esquema XML están descritos en la Tabla 2.