Espacios de nombres XML y atributos

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 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 …

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

Una statement de espacio de nombres predeterminada se aplica a todos los nombres de elementos no prefijados dentro de su scope. Las declaraciones predeterminadas del espacio de nombre no se aplican directamente a los nombres de los atributos ; 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 usan atributos sin nombre de espacio:
Cuando sus elementos tienen un espacio de nombre y esos elementos tienen atributos, entonces no puede haber confusión: los atributos pertenecen a su elemento, que pertenece a su espacio de nombres. Agregar un prefijo de espacio de nombres a los atributos simplemente haría todo más detallado.

Entonces, ¿por qué existen los atributos de espacio de nombres?
Debido a que algunos vocabularios hacen un trabajo útil con la mayoría de los atributos, y pueden hacerlo cuando se mezclan con otros vocabularios. El ejemplo más conocido es XLink .

Por último, W3C XML Schema tiene una manera muy fácil ( ) de declarar sus atributos como si estuvieran en un espacio de nombres, lo que obliga a prefijarlos en sus documentos, incluso cuando usa un espacio de nombres predeterminado.

Ejemplos para ilustrar usando la notación Clark , donde el prefijo del espacio de nombres se reemplaza con la URL del espacio de nombres entre llaves:

    

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"/> 

Hay algo relacionado con este tema de 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 se refieren 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 que lo usa Cliente

Mi statement XSD se veía así:

 < ?xml version="1.0" encoding="utf-8"?>  

La statement de mi atributo Id se veía así:

  

Y mi elemento Cliente usó el atributo de esta manera:

       

Ahora, digamos que quería declarar un documento XML del cliente como este:

 < ?xml version="1.0" encoding="utf-8"?>    

Descubrí que no puedo: cuando el atributo se declara globalmente, no está en el mismo 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 un prefijo para convertirlo en el espacio de nombre predeterminado para los elementos, y una vez con un prefijo para usarlo con los atributos. Así que así es como se vería así:

 < ?xml version="1.0" encoding="utf-8"?>    

Esto es tan poco práctico que decidí deshacerme de todos los atributos globales y declararlos localmente. Lo que en el caso del ejemplo que di aquí se hubiera visto así:

       

Me resulta difícil encontrar algunas referencias sobre lo que estoy hablando aquí en la red. Eventualmente encontré esta publicación en el Stylus XSD Forum donde un tipo llamado Steen Lehmann sugirió declarar el atributo localmente o declararlo dentro de un grupo de atributos

“para que la statement de atributo en sí ya no sea global”

Esta última solución tiene un sabor “hacky”, así que decidí seguir con la primera solución y declarar todos mis atributos localmente.

Lea en 6.1 Espacio de nombres y 6.2 Espacio de nombres predeterminado en w3c.

Básicamente:

El scope de una statement de espacio de nombres que declara un prefijo se extiende desde el comienzo de la etiqueta de inicio en la que aparece hasta el final de la etiqueta final correspondiente

Sin embargo, el texto aquí no parece explicar si significa que a es 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 statement de espacio de nombres se aplica a todos los nombres de elementos y atributos dentro de su scope cuyo prefijo coincida con el especificado en la statement.

Es decir. el espacio de nombres “foo:” solo se aplica a los elementos con el prefijo foo: