xmlns validar targetnamespace schemalocation con xml xsd schema

validar - xsd con xml



Encabezado de esquema XML y configuraciĆ³n de espacio de nombres (3)

La migración de DTD a XSD y, por alguna razón, la transición es irregular. Entiendo cómo definir el esquema una vez que esté dentro de la etiqueta raíz <xs:schema> , pero pasar las cosas de la declaración del encabezado y del espacio de nombres está resultando especialmente confuso para mí.

He estado tratando de seguir el tutorial bien distribuido en W3S pero incluso ese tutorial parece asumir mucho conocimiento por adelantado.

Supongo que lo que busco es una explicación en inglés de King de qué atributos hacen qué, a dónde van y por qué:

  • xmlns
  • xmlns: xs
  • xmlns: xsi
  • targetNamespace
  • xsi: schemaLocation

Y en algunos casos veo diferentes variaciones de estos elementos / atributos, como xsi que parece tener dos notaciones diferentes como xsi:schemaLocation="..." y xs:import schemaLocation="..." .

Supongo que entre todas estas ligeras variaciones parece que no puedo hacer caras o colas de lo que hace cada uno de estos. ¡Gracias de antemano por aportar claridad a esta confusión!


En respuesta a sus consultas:

  1. xmlns : un valor único utilizado en los documentos de instancia para indicar de qué esquema es una instancia el XML (o contra qué esquema se validará). Aunque el espacio de nombres no identifica el archivo de esquema real, debe haber un esquema que defina este espacio de nombres.
  2. xmlns:xs : llamados prefijos de espacio de nombres y, por convención, utilizados en documentos de instancia para indicar de dónde provienen los tipos utilizados en el XML. Puedes pensar en esto como using en C # o imports en VB. Por ejemplo, xmlns:xs="http://mySharedTypes" dice que en este XML algunos de mis tipos provienen del espacio de nombres "http: // mySharedTypes", y estos tipos tendrán el prefijo "xs".
  3. xmlns:xsi - como arriba. De hecho, los prefijos xs y xsi se usan por convención cuando se hace referencia a los espacios de nombres del esquema W3C http://www.w3.org/2001/XMLSchema y http://www.w3.org/2001/XMLSchema-instance . Sin embargo, estos prefijos de espacio de nombres son solo una convención y pueden ser cualquier cosa.
  4. targetNamespace : un valor único que usted pone en su definición de esquema que le da a los tipos que define en el esquema su espacio de nombres. Entonces, si alguien quiere usar los tipos en su esquema, entonces debe incluir un atributo xmlns con los mismos valores que su targetNamespace.
  5. xs:import schemaLocation : esta es convencionalmente una ruta relativa a otro esquema, aunque no todos los procesadores xml lo reconocen. De modo que, opcionalmente, puede vincular a otro esquema en su xs:import como un tipo de acceso directo al propio archivo de esquema. El otro atributo en la importación es el esquema targetNamespace, que es obligatorio.
  6. xsi:schemaLocation - Aunque esto comparte el mismo nombre que el atributo de importación, no es la misma definición. Por convención, el prefijo del espacio de nombres xsi se refiere a los tipos del espacio de nombres http://www.w3.org/2001/XMLSchema-instance , que se utilizan dentro de documentos de instancia, en lugar de documentos de esquema.

Disculpe si lo anterior no está claro, es un poco una pregunta abierta y hay un montón de material que podría escribir para cualquiera de estos puntos. Si necesita claridad sobre cualquiera de los puntos, pregúntele: con gusto le proporcionaré o, alternativamente, crearé una nueva pregunta con un alcance más limitado.


Lo primero que debe comprender son los espacios de nombres XML. Si tiene tiempo que perder, puede leer la especificación . Encontré que esta es una de las especificaciones más claras relacionadas con XML. No importa si no entiendes todo lo que dice, es una buena base. Pero aquí hay un resumen rápido.

Los elementos y atributos XML tienen un nombre. Cuando ve <test att="hello"/> , está mirando un elemento con el nombre "test", en el que tenemos un atributo con el nombre "att". Pero esto no es realmente toda la historia ...

XML es una sintaxis que le permite mezclar contenido de diferentes lenguajes de marcado. Por ejemplo, cuando usa XSLT para convertir un documento XML en una página XHTML, está tratando con al menos tres lenguajes de marcado definidos en XML: el documento de entrada, XSLT y XHTML. Tales mezclas se volverían bastante difíciles si cada una reservara sus propios nombres de elementos / atributos y nunca se permitieran colisiones.

Introduzca espacios de nombres XML. Un espacio de nombres XML define una "esfera" dentro de la cual los nombres de elementos y atributos tienen semántica real. El elemento "plantilla" tiene un significado bien definido en el espacio de nombres XSLT. El elemento "complexType" tiene un significado bien definido en el espacio de nombres del esquema XML. Si desea utilizar cualquiera de los dos en su propio lenguaje de marcado usando XML, entonces es posible siempre que lo haga en un espacio de nombres diferente.

Para asegurarse de que un espacio de nombres sea único, deberá proporcionar un identificador único. La especificación se estableció en el uso de URI, la mayoría de las veces en forma de una URL HTTP. La razón de esto es simple: tales URL tienden a ser buenos identificadores únicos. Pero también es una causa muy común de confusión porque la gente cree que las URL realmente tienen un significado o que se accederá a ellas a través de la red durante el procesamiento de XML. Saber muy bien que este no es el caso! No se requiere que la URL apunte a ningún recurso existente. No pasará por ninguna transformación ni se resolverá en una dirección de red. Incluso si dos URL apuntan exactamente a la misma cosa, en el momento en que difieren en un carácter se consideran espacios de nombres diferentes. Un identificador de espacio de nombres es solo una cadena, y uno distingue entre mayúsculas y minúsculas. Nada mas.

Con la introducción de espacios de nombres, el nombre de un elemento o atributo XML de repente consta de dos partes: un espacio de nombres y un nombre local. Ese "test" en <test/> es solo el nombre local. El llamado "nombre completo" consiste en una combinación invisible del espacio de nombres y el nombre local. A veces se usa la notación {namespace URI}local-name , pero eso no es más que una convención.

Así que ahora necesitamos poder usar espacios de nombres en un documento XML. Para declarar un espacio de nombres, XML tiene un mecanismo codificado. Utiliza la cadena especial xmlns para permitir que se realicen declaraciones de espacio de nombres. Se puede hacer de una de dos maneras: vinculando el espacio de nombres a un prefijo, o declarándolo como el espacio de nombres predeterminado.

Cuando se vincula a un prefijo, el formulario es algo como esto: xmlns:prefix="namespace URI" . Aquí hay un ejemplo en un documento XML:

<foo:root xmlns:foo="http://www.foo.com"> <foo:test /> </foo:root>

Ahora hemos enlazado el espacio de nombres http://www.foo.com al prefijo foo . Siempre que este prefijo se ponga delante del nombre de un elemento o atributo, afirmamos que forman parte de ese espacio de nombres.

Lo que es muy importante tener en cuenta aquí es que el prefijo real no significa absolutamente nada. El siguiente documento XML es semánticamente el mismo:

<bar:root xmlns:bar="http://www.foo.com"> <bar:test /> </bar:root>

El prefijo es simplemente una forma conveniente de representar el espacio de nombres. Nos evita tener que usar el URI por completo cada vez.

El siguiente es el espacio de nombres predeterminado. Se puede declarar un espacio de nombres predeterminado con xmlns="namespace URI" . De manera abstracta, podría pensar que esto vincula un espacio de nombres al prefijo vacío. Una vez más el mismo documento XML, pero esta vez sin prefijos:

<root xmlns="http://www.foo.com"> <test /> </root>

Esto es un poco más conveniente para trabajar. Entonces, ¿por qué tienen prefijos? Comienzan a jugar un papel cuando estamos mezclando contenido de diferentes espacios de nombres:

<root xmlns="http://www.foo.com"> <so:test xmlns:so="http://.com" /> </root>

Esta vez es un documento XML diferente. Nuestro elemento root se encuentra en el espacio de nombres http://www.foo.com , pero el elemento de test se encuentra en http://.com porque nos hemos vinculado a ese prefijo y lo hemos utilizado en la test .

También observa que los espacios de nombres se pueden declarar en cualquier elemento del documento XML. El alcance de esa declaración (y el enlace al prefijo si corresponde) se convierte en ese elemento y su contenido.

Esto puede llegar a ser confuso, incluso más, ya que las declaraciones pueden anularse entre sí. Revisa este documento:

<root xmlns="http://www.foo.com"> <test /> <so:test xmlns:so="http://www..com" xmlns="http://www.bar.com"> <test /> </so:test> </root>

Tómese un momento y averigüe en qué espacio de nombres está cada elemento ... Es un buen ejercicio.

root está en el espacio de nombres http://www.foo.com . El primer elemento de test también se encuentra en ese espacio de nombres, ya que no hemos utilizado un prefijo, pero estamos en el ámbito de ese espacio de nombres predeterminado. El segundo elemento de test con prefijo se encuentra en el espacio de nombres http://www..com porque a eso es a lo que estamos vinculados el prefijo.

Entonces está el tercer elemento de test más interno. ¿En qué espacio de nombres está? No tiene un prefijo, por lo que debe estar en el espacio de nombres predeterminado. PERO, ¡hemos cambiado nuestro espacio de nombres predeterminado en el segundo elemento de prueba! Así que ahora ese elemento más interno pertenece al espacio de nombres http://www.bar.com , no a http://www.foo.com .

Confundido ya? Solo recuerda lo siguiente:

  • Un espacio de nombres es sólo una cadena. Los URI se utilizan como una forma conveniente de tener identificadores únicos.
  • Un prefijo se usa para representar un espacio de nombres, pero su nombre no tiene ningún significado. Solo piénsalo como un marcador de posición.
  • Puede establecer un espacio de nombres predeterminado. Todos los elementos dentro de su alcance que no tienen un prefijo se convierten en parte de él.

Uf. Ahora, en el esquema XML del W3C. ¿Cómo se relaciona todo esto con esto?

Bueno, para empezar, el esquema XML en sí mismo es un lenguaje de marcado definido en XML. Por lo tanto, es lógico que tenga su propio espacio de nombres. Y ese espacio de nombres es oficialmente http://www.w3.org/2001/XMLSchema . Si escribes esa S como minúscula, está mal. ¿Empezando a ver por qué algunas personas realmente odian los espacios de nombres?

Los siguientes tres documentos son exactamente iguales:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> </xsd:schema> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> </xs:schema> <schema xmlns="http://www.w3.org/2001/XMLSchema"> </schema>

Todo lo que importa es que estamos usando cosas del espacio de nombres del esquema XML. Sin embargo, como convención, las personas tienden a usar el prefijo xs o xsd en los esquemas XML.

Cuando tenemos un documento XML, es posible que deseamos especificar dónde se ubican los esquemas. Más de un esquema puede ser relevante para un documento XML, porque como hemos dicho, los idiomas se pueden mezclar en XML. Para decir que un documento XML es una instancia de un esquema, una vez más hay un espacio de nombres especial disponible: http://www.w3.org/2001/XMLSchema-instance . Por convención, tendemos a vincular este espacio de nombres al prefijo xsi . Pero de nuevo, esto no es obligatorio.

Hay un par de atributos definidos en el espacio de nombres de la instancia de esquema. Entre ellos se encuentran schemaLocation y noNamespaceSchemaLocation . Echa un vistazo a este documento:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.foo.com/schema"> </root>

¿Qué ha pasado allí? Primero dijimos que estamos vinculando el prefijo xsi al espacio de nombres http://www.w3.org/2001/XMLSchema-instance . Luego usamos un atributo dentro de ese espacio de nombres: noNamespaceSchemaLocation . Ese atributo nos dice dónde se ubica el esquema para validar aquellas partes del documento que no están en ningún espacio de nombres en particular. El siguiente documento XML es exactamente el mismo, semánticamente:

<root xmlns:huh="http://www.w3.org/2001/XMLSchema-instance" huh:noNamespaceSchemaLocation="http://www.test.com/schema"> </root>

Recuerde, los nombres de prefijo no tienen significado. Son marcadores de posición. Entonces, ¿qué noNamespaceSchemaLocation con ese atributo noNamespaceSchemaLocation ? Básicamente, nos dice dónde podemos ubicar un esquema. Ahora, a diferencia de un URI de espacio de nombres, esto es definitivamente algo que se puede usar para recuperar cosas de una red o almacenamiento local. Un procesador XML que valida contra un esquema declarado en un documento podría intentar obtenerlo.

Luego está el hecho de que se llama noNamespaceSchemaLocation . Un esquema define un "espacio de nombres de destino". Lo que esto hace es indicar de qué espacio de nombres forman parte los elementos y los atributos que define. Pero el espacio de nombres de destino puede omitirse. En ese caso, tenemos un esquema para documentos XML sin espacio de nombres. Se puede hacer referencia a noNamespaceSchemaLocation esquema con noNamespaceSchemaLocation .

En muchos casos, un esquema realmente definirá un espacio de nombres. Para decir qué esquema pertenece a qué espacio de nombres, podemos usar otro atributo del espacio de nombres http://www.w3.org/2001/XMLSchema-instance : schemaLocation . Ese atributo puede contener pares (separados por espacios) de URI de espacio de nombres y URI de esquema. Supongamos que tenemos un esquema para el espacio de nombres http://www.foo.com ubicado en http://www.myschemas.com/foo-schema . Entonces podemos afirmar que de la siguiente manera:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema"> </root>

Aquí hay un ejemplo con varios pares de ubicación de espacio de nombres:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema http://www.bar.com http://www.randomschemas.com/bar-schema"> </root>

Lo que debe recordar aquí es que http://www.w3.org/2001/XMLSchema-instance stuff se usa en documentos XML que son instancias de esquemas. El espacio de nombres http://www.w3.org/2001/XMLSchema es el que se usa para definir los esquemas en sí mismos.

Así que ahora estamos a la altura de los URI y los atributos de aspecto extraño con significados especiales. Eso es lo que pasa con los espacios de nombres: se ven muy complejos hasta que descubres lo simples que son. Simplemente observe de cerca qué prefijo está vinculado a qué URI de espacio de nombres y sepa qué define ese URI.

Hay dos cosas más sobre los esquemas que debo abordar para su pregunta: xs:import y xs:include . Observe cómo he usado la convención del prefijo xs aquí, ya que estamos hablando del esquema XML del W3C.

El elemento de inclusión se puede usar para combinar esquemas con el mismo espacio de nombres de destino . Básicamente, nos permite modular esquemas en partes más pequeñas y juntarlos.

El elemento de importación hace lo mismo, pero para esquemas con diferentes espacios de nombres de destino . Esto nos permite combinar esquemas para diferentes lenguajes de marcado.

Así que para recapitular:

  • xmlns : se utiliza para especificar un espacio de nombres predeterminado.
  • xmlns:prefix : se utiliza para enlazar un espacio de nombres al prefix .
  • http://www.w3.org/2001/XMLSchema : el espacio de nombres para el esquema XML. Por convenio, a menudo están vinculados al prefijo xs , pero esto no es obligatorio ni se hace automáticamente.
  • http://www.w3.org/2001/XMLSchema-instance : el espacio de nombres que define un montón de cosas útiles para declarar los detalles de cómo un documento XML es una instancia de un esquema. Por convenio, a menudo están vinculados al prefijo xsi , pero esto no es obligatorio ni se hace automáticamente.
  • targetNamespace : un atributo que se puede usar en el esquema XML (en el elemento raíz) para especificar para qué espacio de nombres es una definición de esquema.
  • schemaLocation : uno de los atributos definidos por el espacio de nombres http://www.w3.org/2001/XMLSchema-instance , utilizado para indicar dónde se pueden encontrar uno o más esquemas para uno o más espacios de nombres.

Mi último consejo: encuentre una manera conveniente de validar documentos contra esquemas y juegue un poco. Experimenta con espacios de nombres, incluye e importa. Haga documentos utilizando múltiples espacios de nombres y pruebe el alcance.

Después de eso, verifique las especificaciones del propio XML, los espacios de nombres XML y el esquema XML. Es una lectura incondicional, pero si te abres camino, obtendrás un entendimiento que mucha gente todavía parece extrañar después de años de usar XML. Eventualmente todo tendrá sentido.

¡Buena suerte!


  • xmlns="uri1" y xmlns:whatever="uri2" son un nodo de espacio de nombres y no atributos. Su función es decir que cuando ves un elemento en tu documento XML llamado whatever:myElement , entonces el elemento pertenece al espacio de nombres "cualquiera". Este "cualquier espacio de nombres" está identificado por el uri declarado en el nodo de espacio de nombres.
  • targetNamespace es un atributo. Contiene un URI que identifica los elementos, tipos y grupo que define en su esquema.
  • xsi: schemaLocation es bastante diferente. Es un atributo que permite a los analizadores XML encontrar el esquema adjunto a una instancia XML. No lo necesitas en el esquema.
  • Con xs:import puede importar esquemas de diferentes espacios de nombres para usar sus elementos y tipos en su propio esquema. Cuando se utiliza xs:import , el esquema importado y el esquema de importación deben tener un espacio de nombres diferente. Usa xs:include si es el mismo espacio de nombres.