Este documento es una traducción al español de la recomendación del W3C y puede encontrarse en http://www.aafunky.com/w3c/xmlschema/xmlschema-0es.html. 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 José 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 elementos 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 elemento
s 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 key
s 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.