2008-09-03 16 views
35

Estoy tratando de entender cómo funcionan los espacios de nombres en XML. Cuando tengo un elemento como foo: bar, los atributos a menudo no tienen espacios de nombres en ellos. Pero a veces lo harán. ¿El atributo está en el espacio de nombre del elemento, incluso cuando se ha declarado el espacio de nombre predeterminado? Mirando sobre el xsd para xhtml parece que los atributos son parte del esquema y deberían estar en el espacio de nombres para xhtml, pero nunca se presentan de esa manera ...Espacios de nombres XML y atributos

Respuesta

2

Lea en 6.1 Namespace Scoping y 6.2 Namespace Defaulting en w3c.

Básicamente:

El alcance de una declaración de espacio de nombres que se declara un prefijo se extiende desde el comienzo de la etiqueta de comienzo en la que aparece al final de la etiqueta final correspondiente

Sin embargo , el texto aquí no parece explicar si los medios a son foo: a o el espacio de nombres predeterminado en el contexto. Supongo que no se refiere a foo: a, sino más bien al espacio de nombres predeterminado de los documentos a. Teniendo en cuenta esta cita al menos:

Dicha declaración de espacio de nombres se aplica a todos los nombres de elementos y atributos dentro de su alcance cuyo prefijo coincide con el especificado en la declaración.

Ie. el espacio de nombres "foo:" sólo se aplica a los elementos con el prefijo foo:

11

ejemplos para ilustrar el uso de la Clark notation, donde el prefijo de espacio de nombres se sustituye con la dirección URL de espacio de nombres entre llaves:

<bar xmlns:foo="http://www.foo.com/" 
    foo:baz="baz" 
    qux="qux"/> 
<bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/" 
    foo:baz="baz" 
    qux="qux"/> 
<foo:bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/" 
    foo:baz="baz" 
    qux="qux"/> 

es

<{}bar 
    {http://www.foo.com/}baz="baz" 
    {}qux="qux"/> 
<{http://www.foo.com/}bar 
    {http://www.foo.com/}baz="baz" 
    {}qux="qux"/> 
<{http://www.foo.com/}bar 
    {http://www.foo.com/}baz="baz" 
    {}qux="qux"/> 
+2

¿Cómo se explica que en los ejemplos segundo y tercero el atributo 'qux' no herede el espacio de nombres' http: // www.foo.com/'aunque sea el espacio de nombre predeterminado para el elemento? –

46

La mayoría de las veces, los atributos no estarán en ningún espacio de nombres. El namespace spec dice ( énfasis mío):

Una declaración de espacio de nombres por defecto se aplica a todos los elementos sin prefijo nombres dentro de su ámbito de aplicación. Las declaraciones de espacio de nombre predeterminadas hacen no se aplican directamente a atributo nombres; la interpretación de los atributos no prefijados está determinada por el elemento en el que aparecen.

Hay una razón por la que la mayoría de los vocabularios XML utilizan atributos que no son espacios de nombres:
Cuando sus elementos tienen un espacio de nombres y esos elementos tienen atributos, entonces no puede haber ninguna confusión: los atributos pertenecen a su elemento, que pertenece a tu espacio de nombres Agregar un prefijo de espacio de nombres a los atributos simplemente haría todo más detallado.

¿Por qué existen atributos de espacio de nombres?
Porque algunos vocabularios hacen un trabajo útil con atributos en su mayoría, y pueden hacerlo cuando se mezclan con otros vocabularios. El ejemplo más conocido es XLink.

Por último, el esquema XML de W3C tiene una forma muy fácil (<schema attributeFormDefault="qualified">) de declarar sus atributos como miembros de un espacio de nombres, obligando a usar el prefijo en sus documentos, incluso cuando se utiliza un espacio de nombres predeterminado.

+1

Esta es una respuesta muy bien informada, teniendo en cuenta lo que ha dicho aquí, consideraría que esta afirmación es falsa: "Todos los atributos, donde sea que estén, tienen que estar prefijados para pertenecer a un espacio de nombres" Contexto: http://stackoverflow.com/ preguntas/10917416/configuring-an-xml-namespace/10917629 # comment14238724_10917629 (respuesta de Panda) –

+0

@Bart Schuller: Es probable que los atributos pertenezcan a su elemento, pero no es absolutamente necesario. –

+0

"la mayoría de los vocabularios XML usan atributos no espaciados por nombres" probablemente debería ser "la mayoría de los vocabularios XML usan atributos ** no prefijados **", porque, como usted dice correctamente, heredan el espacio de nombres, por lo que son "espacios de nombre" pero simplemente don no tiene un prefijo –

7

Hay algo relacionado con este tema de los atributos/espacios de nombres que me llevó algo de tiempo entender hoy cuando estaba trabajando en un XSD. Voy a compartir esta experiencia con usted en caso de que alguien tenga los mismos problemas.

En el documento de esquema en el que estaba trabajando había un par de atributos globales a los que hacían referencia algunos elementos. Para simplificar las cosas, supongamos que este XSD del que hablo fue sobre un cliente .

Llamemos a uno de estos atributos globales Id. Y el elemento raíz de usarlo cliente

Mi declaración XSD se veía así:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema xmlns="http://schemas.mycompany.com/Customer/V1" 
targetNamespace="http://schemas.mycompany.com/Customer/V1" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

Mi declaración Id atributo era la siguiente:

<xs:attribute name="Id" type="xs:positiveInteger"/> 

y mi cliente elemento utilizó el atributo como este:

<xs:element name="Customer"> 
    <xs:complexType> 
     <xs:attribute ref="Id" use="required"/> 
     <!-- some elements here --> 
    </xs:complexType> 
</xs:element> 

Ahora, vamos a decir que quería declarar una documento XML cliente como esto:

<?xml version="1.0" encoding="utf-8"?> 
<Customer Id="1" xmlns="http://schemas.mycompany.com/Customer/V1"> 
    <!-- ... other elements here --> 
</Customer> 

descubrí que no puedo: cuando el atributo se declara a nivel mundial, no es de la misma espacio de nombres que el elemento que lo hace referencia.

Descubrí que la única solución con el XSD definido así era declarar el espacio de nombres dos veces: una vez sin prefijo para convertirlo en el espacio de nombres predeterminado para los elementos y una vez con un prefijo para usarlo con los atributos. Así que esta es la forma en que habría parecido:

<?xml version="1.0" encoding="utf-8"?> 
<Customer cus:Id="1" xmlns="http://schemas.mycompany.com/Customer/V1" 
xmlns:cus="http://schemas.mycompany.com/Customer/V1"> 
    <!-- ... other elements here --> 
</Customer> 

Esto es tan poco práctico que acabo de decidir deshacerse de todos los atributos globales y les declare de forma local. Wich en el caso del ejemplo que he dado aquí habría parecido esto:

<xs:element name="Customer"> 
    <xs:complexType> 
     <xs:attribute name="Id" type="xs:positiveInteger" use="required"/> 
     <!-- some elements here --> 
    </xs:complexType> 
</xs:element> 

he encontrado que es difícil encontrar algunas referencias acerca de lo que estoy hablando aquí en la red. Al final encontré this post en el Foro XSD Stylus donde un tipo llamado Steen Lehmann sugirió ya sea para declarar el atributo local o declarar dentro de un grupo de atributos

"por lo que la declaración de atributo en sí ya no es global"

Esta última solución tiene un sabor "hacky", por lo que sólo decidió seguir con la primera solución y declarar todos mis atributos a nivel local.

+0

Encontré el mismo problema con las declaraciones globales y locales de los elementos: las declaraciones de elementos "anidados" no heredan el espacio de nombres del padre. Lo que se refiere a los atributos, tenerlos no global significa que también tengo que duplicar la documentación, lo que quiero evitar. ¿Podría dar el ejemplo con atributos globales también? –

Cuestiones relacionadas