En un documento de esquema xml, si tengo tanto targetNamespace como xmlns sin prefijo .
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/" xmlns="http://example.com/">
¿Cuál es la diferencia exacta entre ellos? Mi comprensión es que si tiene un xmlns sin prefijo, todos los elementos sin prefijo obtienen ese espacio de nombres y ... confusamente, lo mismo ocurre con targetNamespace.
Respuestas:
targetNamespace es un "artefacto" de esquema XML; su propósito: indicar qué espacio de nombres XML particular describe el archivo de esquema.
xmlns : debido a que el esquema XML es un documento XML, es posible definir un espacio de nombres XML predeterminado para el archivo XML (esto es lo que hace el atributo xmlns); las implicaciones son múltiples: autoría y composición. Por ejemplo, no es necesario usar un prefijo para los elementos definidos en el esquema, que luego se referencian en otra parte del mismo archivo (por ejemplo, un simpleType global usado como tipo para un atributo o elemento).
Desde mi experiencia, muchos autores de esquemas XML consideran esto como una "mejor práctica" ... por lo que está en el camino correcto.
En términos de XSD, targetNamespace prescribe la parte del espacio de nombres de un nombre calificado de un componente de esquema, que incluye elementos, atributos, grupos y grupos de atributos, y tipos simples y complejos. Algunos de los nombres calificados definidos en un XSD (elementos y atributos) son utilizados "directamente" por un documento de instancia XML. Se puede hacer referencia a otros, como para tipos, a través del atributo xsi: type en documentos XML de instancia. El resto (grupos, grupos de atributos) están ahí para facilitar la composición del esquema (a través de referencias).
También soy de la opinión de que (en general) la gente diseña XSD desde dos ángulos:
para que coincida con un XML existente. En este caso, si su XML usa espacios de nombres, para cada uno de los espacios de nombres usados, terminará con un elemento de esquema XSD con un atributo targetNamespace coincidente.
modelado puro. Luego piensa en targetNamespace similar a un paquete UML, o esquema de base de datos, o un paquete Java, o un espacio de nombres .NET, y todo lo que significa en este caso. Fundamentalmente es un mecanismo para evitar colisiones de nombres; no obstante, también es un mecanismo para dividir modelos en áreas temáticas, etc.
fuente
Para aquellos que todavía están confundidos, considere estos tres xsds. Todos definen un tipo global y una definición de elemento global que hace referencia a él.
Primero, un xsd como el publicado arriba. Utiliza el prefijo 'xsd' para el espacio de nombres del esquema y un espacio de nombres predeterminado para el targetNamespace:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/" xmlns="http://example.com/"> <xsd:element name="aGlobalElement" type="aGlobalType"/> <xsd:simpleType name="aGlobalType"> <xsd:restriction base="xsd:string"/> </xsd:simpleType> </xsd:schema>
Ahora el mismo xsd, pero definiendo y usando un prefijo de espacio de nombres para el espacio de nombres de destino:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/" xmlns:tns="http://example.com/"> <xsd:element name="aGlobalElement" type="tns:aGlobalType"/> <xsd:simpleType name="aGlobalType"> <xsd:restriction base="xsd:string"/> </xsd:simpleType> </xsd:schema>
... y finalmente, una versión que usa un espacio de nombres predeterminado en lugar de 'xsd' para el espacio de nombres del esquema XML:
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/" xmlns:tns="http://example.com/"> <element name="aGlobalElement" type="tns:aGlobalType"/> <simpleType name="aGlobalType"> <restriction base="string"/> </simpleType> </schema>
La mayoría de los autores de esquemas eligen el primero o el último, porque si el espacio de nombres predeterminado está disponible, también podríamos usarlo para algo .
fuente
xmlns
El atributo xmlns establece el espacio de nombre predeterminado del elemento descrito. Por tanto, el espacio de nombres predeterminado se aplica a todos los elementos dentro del elemento descrito, que no declaran explícitamente otro espacio de nombres para sí mismos.
El espacio de nombre predeterminado se establece en un valor estándar para los archivos WSDL: http://www.w3.org/ns/wsdl
targetNameSpace
Este atributo contiene el espacio de nombres de su servicio web. Puede elegir este espacio de nombres libremente, pero hay una convención que dice que el URI debe apuntar al WSDL del servicio.
xmlns: tns
Este espacio de nombres debe establecerse en el mismo URI que el atributo targetNameSpace. De esa forma, puede hacer referencia al espacio de nombres de destino a través de este prefijo de espacio de nombres (tns).
Fuente: http://tutorials.jenkov.com/wsdl/description.html
fuente
targetNamespace
es un atributo delschema
elemento define el espacio de nombres, es decir, el paquete en un archivo XSD. Por convención, usamos URI / URL, pero podríamos usar cualquier cadena.xmlns
es un atributo que se utiliza para hacer referencia a elementos y tipos de datos que provienen del valor del atributo xmlns para el alcance del elemento actual.Por ejemplo:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
está con prefijo, ya quexsd
significa que el espacio de nombres debe tener el prefijoxsd:
xmlns="http://www.w3.org/2001/XMLSchema"
sin prefijo es predeterminadop
significa que el espacio de nombres debe tener el prefijop:
¿Dónde
xmlns:xsd
yxmlns:p
son QNames yxmlns
es el nombre local.La siguiente imagen ayuda a comprender XSD usando la analogía de Java según mi conocimiento:
fuente
Otras respuestas son buenas aquí, por lo que no repetiré sus explicaciones aquí. Sin embargo, si alguien con experiencia en Java encuentra que es más simple, aquí está la analogía que se me ocurrió:
.xsd
el documento es el artefacto /.jar
archivoxmlns
es eldeclaración, declara en la parte superior de sus clases de Java .
Considere (por analogía), si tuviera un solo paquete en su proyecto Java, y todas las clases están declaradas y definidas dentro de una sola clase externa. Por ejemplo,
package com.furniture.models public class FurnitureShop { int noOfTables; int noOfChairs; int noOfBeds; List<Table> tables; List<Chair> chairs; List<Bed> beds; // and now instead of declaring and defining a class for table/chair/bed in a // separate file, you just add it here public static class Table { int height; int width; int length; ... } public static class Chair { String color; ChairType chairType; ... } public static class Sofa { int price; String color; ... } }
Así es como se agrupan diferentes elementos en un solo
.xsd
archivo, para un nuevo esquema.targetNamespace
es el nombre del artefacto que crea. Como puede averiguarlo usted mismo,targetNamespace
se usa al crear un esquema, en un.xsd
archivo.Una vez que
.xsd
se crea el artefacto (o archivo), lo usaría en otros proyectos de la siguiente manera:En un proyecto de Java, importaría la biblioteca, usando
pom.xml
(obuild.gradle
) el archivo de la siguiente manera:<dependency> <groupId>com.furniture</groupId> <artifactId>furniture-apis</artifactId> <version>1.1.1</version> </dependency>
En XML, "importaría" el esquema usando
<furniture xmlns="http://furniture.com"/>
=== APÉNDICE ===
Aclaración -
xmlns
se utiliza tanto como unapackage
declaración, así como laimport
declaración en Java. En el.xsd
archivo,xmlns
actúa como lapackage
declaración " ", mientras que en los.xml
archivos, actúa como laimport
declaración " ".fuente
Después de algunas pruebas exhaustivas con xmllint , creo que encontré la explicación definitiva aquí. Considere el siguiente esquema:
<?xml version="1.0" encoding="utf-8"?> <xsd:schema version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://yyyzzz.com" xmlns:p="http://abced.com" xmlns:q="http://pqr.com" xmlns="http://yyyzzz.com"> <xsd:element name="recipe" type="recipeType" /> <xsd:complexType name="recipeType"> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute name="desc" type="xsd:string" /> <xsd:attribute name="archetype" type="xsd:string" /> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:schema>
El esquema anterior valida el siguiente documento:
<?xml version="1.0"?> <recipe xmlns="http://yyyzzz.com"> Deciphering the purpose of targetNamespace </recipe>
La razón por la que funciona es porque xmlns = "http://yyyzzz.com" también se une automáticamente al elemento que está siendo definido por el esquema. Eso significa que también se une al elemento RecetaType .
Ahora, con el mismo documento xml pero con un esquema ligeramente modificado como el que se muestra a continuación, también valida y observa de cerca la diferencia:
<?xml version="1.0" encoding="utf-8"?> <xsd:schema version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://yyyzzz.com" xmlns="http://eigenfield.aparicio.com" xmlns:EGboy="http://yyyzzz.com"> <xsd:element name="recipe" type="EGboy:recipeType" /> <xsd:complexType name="recipeType"> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute name="desc" type="xsd:string" /> <xsd:attribute name="archetype" type="xsd:string" /> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:schema>
Ignore si los otros xmlns desaparecieron, pero en su lugar observe de cerca type = "EGboy: receteType" . Ya no podemos confiar en el xmlns porque tiene un valor diferente, por lo tanto, debemos poner el prefijo EGboy delante de receteType .
El documento xml ni siquiera se preocupa por el prefijo EGboy, este prefijo es solo para que el esquema haga referencia a los xmlns adecuados en caso de que haya muchos.
fuente