targetNamespace y xmlns sin prefijo, ¿cuál es la diferencia?


77

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.


1
Puede que me falte algún conocimiento sobre este tema, pero ¿no podría la respuesta ser simplemente: xmlns es el espacio de nombres predeterminado para ESTE documento (el documento de esquema), mientras que targetNamespace es el espacio de nombres que valida este documento de esquema? ¿Y de esta manera xmlns y targetNamespace son dos cosas diferentes?
partir del

@Vering mis hallazgos de prueba coincide con su primera oración, sí, targetNamespace definitivamente se refiere al documento que valida el esquema. La presencia de targetNamespace también parece necesitar la presencia de 'xmlns' o 'xmlns: xxx'. De hecho, puede combinar muchos 'xmlns: xxx', 'xmlns: yyy' y 'xmlns' juntos y todavía se valida.
eigenfield

Respuestas:


80

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.


28

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 .


15

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


El URI para targetNamespace no "apunta a" nada, es solo un identificador para el espacio de nombres. Puede ser el URI de un servicio web, pero sigue siendo solo para etiquetar el espacio de nombres.
Suncat2000

4

espacio de nombres significa como alcance

targetNamespacees un atributo del schemaelemento 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 que xsdsignifica que el espacio de nombres debe tener el prefijoxsd:
  • xmlns="http://www.w3.org/2001/XMLSchema" sin prefijo es predeterminado
  • xmlns: p = "http://www.example.com/People" tiene el prefijo, ya que psignifica que el espacio de nombres debe tener el prefijop:

¿Dónde xmlns:xsdy xmlns:pson QNames yxmlns es el nombre local.

La siguiente imagen ayuda a comprender XSD usando la analogía de Java según mi conocimiento:

ingrese la descripción de la imagen aquí


1

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

  1. .xsdel documento es el artefacto / .jararchivo
  2. xmlns es el

    package com.example
    

    declaració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 .xsdarchivo, para un nuevo esquema.

  1. targetNamespacees el nombre del artefacto que crea. Como puede averiguarlo usted mismo, targetNamespacese usa al crear un esquema, en un .xsdarchivo.

Una vez que .xsdse 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(o build.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 -

  1. xmlnsse utiliza tanto como una packagedeclaración, así como la importdeclaración en Java. En el .xsdarchivo, xmlnsactúa como la packagedeclaración " ", mientras que en los .xmlarchivos, actúa como la importdeclaración " ".

-1

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.