Principal  |   Otras traducciones
Logotipo del SIDAR. LLeva a la página principal. Traducciones:

Nota de Traducción

Traducción al español: José Manuel Alonso.

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.


W3C

Esquema XML Parte 0: Fundamentos

Recomendación del W3C, 2 de Mayo de 2001

Esta versión:
http://www.w3.org/TR/2001/REC-xmlschema-0-20010502/
Última versión:
http://www.w3.org/TR/xmlschema-0/
Versión anterior:
http://www.w3.org/TR/2001/PR-xmlschema-0-20010330/
Editor:
David C. Fallside (IBM) fallside@us.ibm.com

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

 

Resumen

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.

Estado de este Documento

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.

Tabla de Contenidos

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

Apéndices

A Reconocimientos
B Tipos Simples y sus Propiedades
C Uso de Entities [Uso de Entidades]
D Expresiones Regulares
E Índice



1 Introducción

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.

 

2 Conceptos Básicos: Hoja de Pedido

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:

Hoja de Pedido, po.xml
<?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.

2.1 El Esquema de la Hoja de Pedido

El esquema de la hoja de pedido está contenido en el archivo po.xsd:

El Esquema de la Hoja de Pedido , 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.

2.2 Definiciones de Tipos Complejos, Declaración de Elementos y Atributos

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:

Definición del Tipo direccionEEUU
  <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.

Definición del TipoHojaPedido
 <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.

2.2.1 Restricciones de Ocurrencia

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.

 

2.2.2 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.

2.2.3 Conflictos de Nombres

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.

2.3 Tipos Simples

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:

Definición de miEntero, rango de 10000-99999
<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":

Definición del Tipo Simple "SKU"
<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:

Utilización de la Propiedad Enumeration
<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.

2.3.1 Tipos Lista

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:

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:

Tipo Lista para Seis Estados EEUU
<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.

2.3.2 Tipos Unión

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:

Tipo Unión para Códigos
<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.

2.4 Definiciones de Tipos Anónimos

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):

Dos Definiciones de Tipo Anónimo
<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.

2.5 Contenido de Elementos

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.

2.5.1 Tipos Complejos desde Tipos Simples

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:

Derivación de un Tipo Complejo a partir de un Tipo Simple
 <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.

2.5.2 Contenido Mixto

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:

Fragmento de Carta de un Cliente
<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:

Fragmento de un Esquema para Carta de Cliente
<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.

2.5.3 Contenido Vacío

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:

Un Tipo Complejo 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:

Forma Abreviada para definir un Tipo Complejo Vacío
<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.

2.5.4 anyType [cualquierTipo]

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.

2.6 Anotaciones

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:

Anotaciones en Declaraciones de Elementos y Definiciones de Tipos Complejos
<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.

2.7 Construcción de Modelos de Contenido

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:

Condiciones Anidadas y Grupos de Secuencias
<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:

Un Grupo 'All'
<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:

Ejemplo No Legal con un Grupo 'All'
<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.

2.8 Grupos de Atributos

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:

Añadir Atributos a la Declaración de Tipo Anónima
<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:

Añadir Atributos Utilizando un Grupo de Atributos
<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.

2.9 Valores Nulos

Uno de los elementos de la hoja de pedido listada en po.xml, el cortaCesped, no tiene un elemento fechaEnvio. En el contexto de nuestro escenario, el autor del esquema puede haber hecho dichas ausencias intencionadamente para indicar elementos que aún no han sido enviados. Pero en general, la ausencia de un elemento no tiene un significado particular: puede indicar que la información es desconocida, o no es aplicable, o el elemento puede estar ausente por cualquier otra razón. A veces es deseable representar un elemento no enviado, información desconocida, o información no aplicable de manera explícita con un elemento, en vez de un elemento ausente. Por ejemplo, sería deseable representar un valor "null" [nulo] que es enviado desde o hacia una base de datos relacional con un elemento que esté presente. Tales casos pueden representarse utilizando el mecanismo nulo del Esquema XML que permite que un elemento pueda aparecer o no con un valor no-nulo.

El mecanismo nulo del Esquema XML funciona como una señal nula "fuera de banda". Es otras palabras, no hay un valor nulo que aparezca como contenido de un elemento, sino que existe un atributo que indica que el contenido del elemento es nulo. Para ilustrar esto, modificamos la declaración del elemento fechaEnvio para que pueda aceptar valores nulos:

<xsd:element name="fechaEnvio" type="xsd:date" nillable="true"/>

Y para representar explícitamente que fechaEnvio tiene un valor nulo en el documento instancia, ponemos el valor del atributo nulo (el del espacio de nombres del Esquema XML para instancias) a true:

<fechaEnvio xsi:nil="true"></fechaEnvio>

El atributo nil [nulo] se define como parte del espacio de nombres para instancias del Esquema XML, http://www.w3.org/2001/XMLSchema-instance, y así puede aparecer en el documento instancia con un prefijo (como xsi:) asociado con ese espacio de nombres. (Como con el prefijo xsd:, el prefijo xsi: es utilizado sólo por convención). Nótese que el mecanismo nulo se aplica sólo a valores de elementos, y no a valores de atributos. Un elemento con xsi:nil="true" puede no tener contenido de elementos pero puede tener atributos.

 

3. Conceptos Avanzados I: Espacios de Nombres, Esquemas y Calificación

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.

3.1 Espacios de Nombres y Locales Sin Calificar

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:

Una Hoja de Pedido con Locales Sin Calificar, po1.xml
<?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.

3.2 Locales Calificados

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:

Modificaciones a po1.xsd para Locales Calificados
<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:

Una Hoja de Pedido con Locales Calificados 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:

Una Hoja de Pedido con Locales Calificados por Defecto, 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:

Requirir la Calificación de un Único Atributo
<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:

Instancia con un Atributo Calificado
<?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>

3.3 Declaraciones Locales contra Globales

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.

Versión Modificada de po1.xsd utilizando sólo declaraciones globales de elementos
<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".

3.4 Espacios de Nombres Sin Declarar

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.

 

4. Conceptos Avanzados II: Hoja de Pedido Internacional

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.

4.1 Un Esquema en Múltiples Documentos

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:

Esquema de la Hoja de Pedido Internacional, 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:

Direcciones para el Esquema de la Hoja de Pedido Internacional, address.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">
   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.

4.2 Derivación de Tipos por Extensión

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:

Ejemplo
 <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>

4.3 Uso de Tipos Derivados en Documentos Instancia

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.

Una Hoja de Pedido Internacional, ipo.xml
<?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.

4.4 Derivación de Tipos Complejos por Restricción

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:

Derivación de ElementosConfirmados por Restricción a partir de Elementos
<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

4.5 Redefinición de Tipos y Grupos

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:

Utilización de redefine en la Hoja de Pedido Internacional
<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:

Fragmento de ipo.xml utilizando Dirección Redefinida
 ....
 <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.

4.6 Grupos de Sustitución

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:

Declaración de Elementos Sustituibles por comentario
<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:

Fragmento de ipo.xml con Elementos Sustituidos
....
 <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.

4.7 Elementos y Tipos Abstractos

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:

Esquema para Vehículos
<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.

4.8 Control de la Creación y Uso de Tipos Derivados

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:

Prevención de Derivaciones por Restricción de Direccion
<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:

Prevención de Cambios en Propiedades de Tipos Simples
<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:

Derivación Legal de codigoPostal
<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:

Derivación Ilegal de codigoPostal
<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:

Prevención de Derivaciones por Restricción de Dirección en una Instancia
<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.

 

5. Conceptos Avanzados III: El Informe Trimestral

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.

Informe Trimestral, 4Q99.xml
<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.

El Esquema del Informe, report.xsd
<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>

5.1 Especificar Unicidad

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:

Un Valor Único Compuesto
 <unique name="cualquiera1">
  <selector xpath="r:regiones/r:zip"/>
  <field    xpath="@codigo"/>
  <field    xpath="r:producto/@numero"/>
 </unique>

5.2 Definición de Claves y sus Referencias

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.

5.3 Restricciones del Esquema XML frente a Atributos ID de XML 1.0

XML 1.0 proporciona un mecanismo de unicidad utilizando el atributo ID que es asociado con los atributos IDREF y IDREFS. Este mecanismo también está presente en el Esquema XML a través de los tipos simples ID, IDREF, y IDREFS que pueden ser utilizados para declarar atributos del estilo de los de XML 1.0. El Esquema XML también introduce mecanismo nuevos que son más flexibles y potentes. Por ejemplo, los mecanismos del Esquema XML pueden ser aplicados a cualquier contenido de elemento o atributo, sin importar su tipo. Por contra, ID es un tipo de atributo y por tanto no puede ser aplicado a atributos, elementos o a su contenido. Más aún, el Esquema facilita la posibilidad de especificar el ámbito dentro del cual se aplica la unicidad mientras que el ámbito de un ID es fijado a todo el documento. Finalmente, el Esquema facilita la posibilidad de crear keys o una keyref a partir de combinaciones del contenido de elementos y atributos mientras que el ID no tiene esta posibilidad.

5.4 Importación de Tipos

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:

Definición de Analista por Extensión de direccionEEUU
<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:

Documento Instancia que Conforma con el Esquema de Informes con el Tipo Analista
<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.

5.4.1 Bibliotecas de Tipos

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:

Ejemplo de Tipo de Moneda en una Biblioteca de Tipos
<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.

5.5 Elemento [Elemento Cualquiera], Atributo Any [Atributo Cualquiera]

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:

Informe Trimestral con HTML, 4Q99html.xml
<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:

Modificación al informePedido para permitir HTML en la Instancia
<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.

Tipo Text [Tipo Texto ]
<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:

Tabla 4. Atributo Namespace en Any
Valor del Atributo Namespace Contenido de Elemento Permitido
##any Cualquier XML bien formado de cualquier espacio de nombres (por defecto)
##local Cualquier XML bien formado y sin calificar, es decir, no declarado como perteneciente a un espacio de nombres
##other Cualquier XML bien formado que no es del espacio de nombres del tipo que está siendo definido
"http://www.w3.org/1999/xhtml ##targetNamespace" Cualquier XML bien formado perteneciente a cualquier espacio de nombres perteneciente a la lista (elementos separados por espacios en blanco); ##targetNamespace es un atajo para el espacio de nombres del elemento que está siendo definido

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:

Modificación a la Declaración de ejemploHTML para Permitir Atributos HTML
<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:

Un atributo HTML en el elemento ejemploHTML
....
  <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.

5.6 schemaLocation [ubicación del esquema]

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:

Utilización de schemaLocation en el Informe Trimestral, 4Q99html.xml
<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.

5.7 Concordancia

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.


 

A Reconocimientos

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.

B Tipos Simples y sus Propiedades

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
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    

C Uso de Entities [Uso de Entidades]

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:

Declaración y referenciación de una entidad en un documento instancia.
<?xml version="1.0" ?>
<!DOCTYPE hojaPedido [
<!ENTITY eacute "é">
]>
<hojaPedido xmlns="http://www.example.com/PO1"
               fechaPedido="1999-10-20>
 <!-- etc. --> 
  <ciudad>Montr&eacute;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:

Utilización de un elemento en lugar de una entidad 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.

D Expresiones Regulares

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&#xF1;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

E Índice

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.

 

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.

Los tipos simples del Esquema XML están descritos en la Tabla 2.

 


Principal  |   Otras traducciones