attributeformdefault - xmlns:xsi
¿Por qué necesitamos targetNamespace? (4)
Me gustaría entender el objetivo de targetNamespace como se usa tanto en XML Schema como en WSDL. De hecho, para mantener las cosas simples, limitemos esta pregunta a XML Schema.
Siento que entiendo completamente la noción de espacios de nombres XML (simples). Por convención utilizamos URI / URL, pero podríamos usar cualquier cadena, que luego asignamos a un prefijo para su reutilización por nodos y atributos XML, o simplemente como el espacio de nombres predeterminado para el alcance en cuestión. Hasta aquí todo bien ?
Ahora ingresa el Esquema XML. Por algún motivo, los inventores de XML Schema consideraron que la noción de espacios de nombres simples no era suficiente y tuvieron que introducir el targetNamespace. Mi pregunta es: ¿qué beneficio significativo presenta un targetNamespace que no podría ser proporcionado por un espacio de nombres XML normal? Si un documento XML hace referencia a un documento xsd, ya sea por schemaLocation o con una declaración de importación, en cualquier caso doy la ruta al documento xsd real al que se hace referencia. Esto es lo que define de manera única el esquema al que me refiero. Si además quiero vincular este esquema a un espacio de nombres particular en mi documento de referencia, ¿por qué debería estar obligado a replicar el targetNamespace preciso ya definido en el esquema XML al que me refiero? ¿Por qué no podría simplemente redefinir este espacio de nombres, sin embargo, quiero dentro del documento XML en el que este espacio de nombres se utilizará para referirse a ese documento particular de Esquema XML al que quiero hacer referencia?
Actualizar:
Para dar un ejemplo, si tengo lo siguiente en un documento de instancia XML:
<p:Person
xmlns:p="http://contoso.com/People"
xmlns:v="http://contoso.com/Vehicles"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://contoso.com/schemas/Vehicles
http://contoso.com/schemas/vehicles.xsd
http://contoso.com/schemas/People
http://contoso.com/schemas/people.xsd">
<name>John</name>
<age>28</age>
<height>59</height>
<v:Vehicle>
<color>Red</color>
<wheels>4</wheels>
<seats>2</seats>
</v:Vehicle>
</p:Person>
¿Por qué, por ejemplo, el esquema people.xsd necesita definir un targetNamespace que sea "http://contoso.com/schemas/People"? ¿Por qué necesitamos la definición targetNamespace en el documento xsd en absoluto? Me parece que todo lo que tiene que ganar desde la parte del espacio de nombres de schemaLocation ya está contenido en el documento de instancia XML. ¿Cuál es el beneficio de imponer la existencia de un targetNamespace con el mismo valor en el documento xsd?
Pregunta de seguimiento a la respuesta de Pablo:
¿Puede darme un ejemplo concreto donde tales "choques" entre los nombres de elementos xsd se vuelvan aparentes y eso explique la necesidad de targetNamespace?
Bien, aquí hay un intento de responder mi propia pregunta. Avísame si te parece coherente. Ver los ejemplos en la página vinculada por Pablo me ayudó.
Si tomamos el ejemplo de instancia XML en la pregunta original anterior, tenemos dos referencias a la definición del elemento del vehículo. Uno es explícito y visible en el documento de instancia XML en sí, pero también debemos imaginar que el esquema XML person.xsd vuelve a hacer referencia a la misma definición de vehículo como un elemento secundario permitido de persona. Si utilizáramos espacios de nombres normales en los que a cada documento se le permitiera definir su propio espacio de nombres para el vehículo, ¿cómo sabríamos que la instancia XML hace referencia a la misma definición del esquema XML para el vehículo que la persona.xsd? La única forma es aplicando un concepto de espacio de nombres que sea más estricto que el simple original y que se debe escribir exactamente de la misma manera en varios documentos.
Si no estuviera escribiendo esto en una tableta, proporcionaría un ejemplo de código, pero aquí intentaré describir el ejemplo que tengo en mente.
Imagine que tenemos dos definiciones diferentes de esquemas XML para un elemento de vehículo. location1 / vehicles.xsd contendría la definición que valida el ejemplo de la pregunta de esta publicación (que contiene color, ruedas y asientos de elementos secundarios), mientras que location2 / vehicles.xsd contendría una definición completamente diferente para un elemento del vehículo (por ejemplo, , con elementos secundarios año, modelo y volumen). Ahora, si el documento de instancia XML se refiere al esquema de ubicación1, como es el caso en el ejemplo anterior, pero person.xsd dice que el elemento de persona puede contener un elemento hijo de vehículo del tipo definido en el esquema de ubicación2, entonces sin la noción de un targetNamespace, la instancia XML validaría, aunque claramente no tiene el tipo correcto de vehículo como elemento hijo de su elemento persona.
Los espacios de nombres de destino nos ayudan a asegurarnos de que si dos documentos diferentes hacen referencia al mismo tercer Esquema XML, ambos están de hecho haciendo referencia al mismo Esquema y no solo a un Esquema que contiene elementos que son similares, pero no idénticos entre sí. .
¿Eso tiene sentido?
P: "Por convención utilizamos URI / URL, pero podríamos usar cualquier cadena, que luego asignamos a un prefijo para su reutilización por nodos y atributos XML, o simplemente como el espacio de nombre predeterminado para el alcance en cuestión".
A: Sí, exactamente.
P: "Por alguna razón, los inventores de XML Schema sintieron que la noción de espacios de nombres simples no era suficiente y tuvieron que introducir el targetNamespace".
A: http://www.liquid-technologies.com/Tutorials/XmlSchemas/XsdTutorial_04.aspx
Romper esquemas en múltiples archivos puede tener varias ventajas. Puede crear definiciones reutilizables que se puedan usar en varios proyectos. Hacen que las definiciones sean más fáciles de leer y de la versión, ya que dividen el esquema en unidades más pequeñas que son más fáciles de administrar.
...
Todo esto funciona bien sin espacios de nombres, pero si diferentes equipos comienzan a trabajar en diferentes archivos, entonces tienes la posibilidad de conflictos de nombres, y no siempre sería obvio de dónde viene una definición. La solución es colocar las definiciones para cada archivo de esquema dentro de un espacio de nombres distinto.
Aclaración:
El objetivo principal de XML Schemas es declarar "vocabularios".
Estos vocabularios se pueden identificar por un espacio de nombre que se especifica en el atributo targetNamespace.
El esquema (un documento XML) puede tener un "espacio de nombres". El "vocabulario" que describe el documento puede tener un "targetNamespace".
Así como los Esquemas XML proporcionan un nivel de abstracción más alto que los DTD SGML (los arquitectos originales de las DTD de pensamiento XML fueron suficientes), los "Esquemas de objetivo" del Esquema XML brindan un nivel de abstracción sobre "espacios de nombres simples".
''Espero que ayude
Creo que ayuda ver tanto el documento de instancia como el documento de esquema al mismo tiempo para entender qué targetNamespace hace. Considere esto (basado en su documento de instancia):
<p:Person
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://localhost:8080/scribble/xml/Person"
xmlns:v="http://localhost:8080/scribble/xml/Vehicle"
xsi:schemaLocation="
http://localhost:8080/scribble/xml/Person
http://localhost:8080/scribble/xml/person.xsd">
<name>John</name>
<age>28</age>
<height>59</height>
<v:Vehicle>
<color>Red</color>
<wheels>4</wheels>
<seats>2</seats>
</v:Vehicle>
</p:Person>
No hay un espacio de nombres predeterminado especificado para el documento, pero p: * y v: * tienen alias a NS URI específicos. Ahora eche un vistazo al documento de esquema en sí mismo:
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://localhost:8080/scribble/xml/Person"
elementFormDefault="qualified"
xmlns:v="http://localhost:8080/scribble/xml/Vehicle">
<import
namespace="http://localhost:8080/scribble/xml/Vehicle"
schemaLocation="http://localhost:8080/scribble/xml/v.xsd"/>
<element name="Person">
<complexType>
<sequence>
<element name="name" form="unqualified" type="NCName"/>
<element name="age" form="unqualified" type="integer"/>
<element name="height" form="unqualified" type="integer"/>
<element ref="v:Vehicle"/>
</sequence>
</complexType>
</element>
</schema>
y
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://localhost:8080/scribble/xml/Vehicle"
elementFormDefault="qualified">
<element name="Vehicle">
<complexType>
<sequence>
<element name="color" form="unqualified" type="NCName"/>
<element name="wheels" form="unqualified" type="integer"/>
<element name="seats" form="unqualified" type="integer"/>
</sequence>
</complexType>
</element>
</schema>
Si observa los atributos en las etiquetas, el espacio de nombre predeterminado es " http://www.w3.org/2001/XMLSchema " para ambos documentos de esquema ... pero el targetNamespace es el que se utiliza como el espacio de nombres con alias en el documento de instancia.
targetNamespace es el espacio de nombres esperado de las instancias independientemente del espacio de nombres de los documentos de esquema y cualquier otro espacio de nombres especificado en el documento de instancia.
Me parece útil pensar que es como organizar una fiesta en la que tengas una lista de invitados y invitados con etiquetas de identificación. Piense en targetNamespace en los documentos de esquema como los nombres en la lista de invitados. Los xmlns, con alias o no, en los documentos de instancia son como las etiquetas de nombre de los invitados. Siempre que tenga la lista de invitados (que milagrosamente incluye una fotocopia de su identificación emitida por el estado), cada vez que encuentre a alguien puede validar su identidad. Si te encuentras con alguien con una etiqueta que no concuerde con los parámetros adjuntos, puedes asustarte (es decir, lanzar un error).
Con el esquema / instancias, tiene:
Schemas:
targetNamespace="http://localhost:8080/scribble/xml/Person"
targetNamespace="http://localhost:8080/scribble/xml/Vehicle"
Ejemplo:
xmlns:p="http://localhost:8080/scribble/xml/Person"
xmlns:v="http://localhost:8080/scribble/xml/Vehicle"
O ... cualquier invitado apodado "v" que encuentre en cualquier lugar de la fiesta (salvo reglas especiales que indiquen lo contrario), en cualquier piso de la casa o en el patio trasero o en la piscina, combine mejor con la descripción de un invitado en el huésped lista nombrada http://localhost:8080/scribble/xml/Vehicle . o son un intruso.
Esas reglas especiales pueden decir algo como, V solo puede pasar el rato si están inmediatamente al lado de P, o P solo puede pasar el rato si V está presente. En este caso, P tiene que colgar cuando V está ahí, pero V puede ir prácticamente a cualquier lugar que quieran sin que A esté allí.
De esta forma, un esquema puede ser increíblemente flexible, definiendo prácticamente cualquier estructura de datos deseada y ser capaz de rastrear lo que sucede simplemente igualando los espacios de nombres (por defecto o prefijados) de cualquier elemento dado al TNS y al esquema asociado.
No está claro para mí exactamente lo que estás preguntando. Claramente, un esquema puede contener definiciones de componentes en muchos espacios de nombres diferentes, y tiene que haber alguna manera de decir "Esta es una declaración del elemento E en el espacio de nombres N". Los diseñadores de XSD eligieron diseñar el lenguaje para que todas las declaraciones en un documento de esquema pertenezcan al mismo espacio de nombres, llamado el espacio de nombres de destino del módulo. Podría haber sido empaquetado de manera diferente, pero la diferencia sería muy superficial. ¿Qué crees que está mal con la decisión de alinear módulos con espacios de nombres?
Usted parece estar en el camino correcto. Haré algunos puntos aquí que podrían ayudar.
- Dentro de un documento de instancia, utiliza espacios de nombres XML para identificar el espacio de nombres en el que se encuentra un elemento o atributo.
- Dentro de un documento de esquema, declaras los elementos y atributos que aparecerán en las instancias. ¿En qué espacio de nombres están declarados? Esto es para lo que targetNamespace es.
- La ubicación del documento de esquema y el espacio de nombre no son lo mismo. Es bastante común tener múltiples documentos .xsd con el mismo targetNamespace. (Pueden incluirse o no, pero normalmente se incluirán entre sí).
- Los documentos de instancia no siempre tienen un elemento xsi: schemaLocation para indicar a los analizadores dónde ubicar los esquemas. Se pueden usar varios métodos para decirle a un analizador dónde ubicar los documentos de esquema relevantes. Un XSD puede estar ubicado en el disco local o en alguna dirección web y esto no debería afectar el espacio de nombres de los elementos que contiene.
- xsi: schemaLocation es una pista. Los analizadores pueden localizar el esquema para el espacio de nombres dado en otro lugar, lo que implica que deben poder saber para qué espacio de nombres es un esquema.
- Las herramientas, como las herramientas de enlace de datos, precompilarán los esquemas y producirán código que reconozca los documentos válidos. Estos deben ser capaces de conocer los espacios de nombres de los elementos declarados.
Creo que lo que supondría es que el documento de instancia podría especificar el espacio de nombres de los elementos y atributos declarados en algún documento de esquema, utilizando xsi: schemaLocation. Eso no funciona. Por un lado, el analizador puede localizar otros documentos de esquema además de los enumerados, y necesita saber para qué espacio de nombres están. Por otro, dificultaría o imposibilitaría el razonamiento sobre los esquemas: no sería posible mirar un esquema y conocer los espacios de nombres a los que pertenecía todo porque esa decisión se pospondría hasta que se escribiera una instancia.