Espacios de Nombres
Como vimos anteriormente, de una forma o de otra es necesarios resolver el conflicto entre un elemento
title definido en slideshow.dtd y el definido en xhtml.dtd.
En el ejercicio anterior, subrayamos el nombre para ponerlo en un "espacio de nombres" diferente. En esta sección, veremos cómo
suar el espacio de nombres de XML estándard para hacer algo
sin renombrar el elemento.
|
Nota:
En este momento, los analizadores Java XML no soportan nombres de espacios. Esta sección es sólo para información.
|
El objetivo principal de la especificación de nombres de espacios es permitir que el autor del documento le diga al analizador qué DTD
usar cuando analice un elemento dado. El analizador puede entonces consultar el DTD para una definición de elemento. Por supuesto,
también es importante evitar que el analizador aborte cuando se encuentra una definición de "duplicado", y que todavía siga
generando errores si el documento referencia un elemento sin cualificar.
|
Nota:
Los espacios de nombres se aplican tanto a atributos como a elementos. En esta sección, sólo hemos considerado elementos. Para
más información sobre los atributos, puedes ver la especificación en
http://www.w3.org/TR/REC-xml-names/.
|
Definir un Espacio de Nombres
Para definir un espacio de nombres al que pertenece un elemento, es necesario añadir un
atributo a la definición del elemento, donde el nombre del atributo
sea xmlns ("xml namespace"). Por ejemplo, podríamos hacer esto
en slideshow.dtd añadiendo una entrada como la siguiente en la lista de definición de atributos del elemento
title.
<!ELEMENT title (%inline;)*>
<!ATTLIST title
xmlns CDATA #FIXED "http://www.example.com/slideshow"
>
Declarar el atributo como FIXED tiene varias características importantes.
- Evita que el documento especifique cualquier valor no correspondiente al atributo xmlns (como se
describe en Definir atributos en un DTD).
- El elemento definido en este DTD se hace único (como el analizador entiende el atributo xmlns), por eso
no genera conflictos con un elemento que tenga el mismo nombre en otro DTD. Esto permite que múltiples DTDs usen el mismo
nombre de elemento sin generar un error del analizador.
- Cuando un documento especifica el atributo xmlns para una etiqueta, el documento selecciona la
definición de elemento con un atributo correspondiente.
Cada nombre de elemento en nuestro DTD obtendría extamente el mismo atributo con el mismo valor. Observa que estamos
usando un string CDATA para suministrar el URI.
En este caso, hemos especificado una URL. Pero podríamos haber
especificado una URN, posiblemente especificando un permiso como
urn: en lugar de http:.
Referenciar un Espacio de Nombres
Cuando un documento usa un nombre de elemento que existe sólo en uno de los ficheros .dtd que
referencia, el nombre no necesita estar cualificado. Pero cuando se usa un nombre de elemento que tiene varias definiciones, se
necesita alguna suerte de cualificación.
|
Nota:
Un nombre de elemento está siempre cualificado para su espacio de nombres por defecto, según se defina en el nombre del
fichero DTD en que el reside. Mientras que haya sólo una definición para el nombre, la cualificación está implícita.
|
Cualificamos una referencia a un nombre de elemento especificando el atributo xmlns, como se ve
aquí:
<title xmlns="http://www.example.com/slideshow"
Overview
</title>
El espacio de nombres se aplica a ese elemento, y a cualquier elemento contenido dentro de él.
Definir un Prefijo de Espacio de Nombres
Cuando sólo necesitamos una referencia a un espacio de nombres, no es mucho trabajo, pero cuando necesitamos hacer la misma
referencia varias veces, añadir el atributo xmlns se convierte en pesado. También hace dificil cambiar el
nombre del espacio de nombres más tarde.
La alternativa es definir un prefijo de espacio de nombres, que es tan secillo como especificar xmlns,
dos puntos (:) y el nombre del prefijo antes del valor del atributo, como se ve aquí:
<sl:slideshow xmlns:sl='http:/www.example.com/slideshow'
...>
...
</sl:slideshow>
Esta definición configura sl como un prefijo que puede usarse para cualificar el nombre del elemento actual y
cualquier elemento dentro de él. Como el prefijo puede usarse en cualquier elemento contenido, tiene más sentido definirlo en el
elemento raíz del documento XML, como se ve aquí.
|
Nota:
El URI del espacio de nombres puede contener caracteres que no están permitidos en un nombre XML, por eso no puede usarse
directamente como prefijo. La definición de prefijo asocia un nombre XML con la URI, lo que permite usar el nombre del prefijo en
su lugar. Lo que hace más sencillo cambiar las referencias a la URI en el futuro.
|
Cuando el prefijo se usa para cualificar un nombre de elemento, la etiqueta final también incluye el prefijo, como se muestra aqui:
<sl:slideshow xmlns:sl='http:/www.example.com/slideshow'
...>
...
<slide>
<sl:title>Overview<sl:title>
</slide>
...
</sl:slideshow>
Finalmente podemos observar que se pueden definir varios prefijos en el mismo elemento, como se muestra aquí:
<sl:slideshow xmlns:sl='http:/www.example.com/slideshow'
xmlns:xhtml='urn:...'>
...
</sl:slideshow>
Con esta clase de arreglo, todos las definiciones de prefijos están juntas en un lugar, y podemos usarlas en cualquier lugar en el que
se necesiten en el documento. Este ejemplo también sugiere el uso de URN para definir el prefijo xhtml, en
lugar de una URL. Esta definición permitiría a la aplicación referenciar una copia local del DTD XHTML o alguna versión copiada, con un
potencial impacto benéfico sobre el rendimiento.