Espacios de nombres (Namespaces)
Autor: F. Javier García Castellano Web: http://www.genura.org/~fjgc, Mail: fjgc@decsai.ugr.es |
(C) GeNeura Team Web: http://decsai.ugr.es, Mail: todos@geneura.ugr.es |
El objetivo principal de la especificación de espacios de nombre es permitir que el autor del documento le diga al analizador o parser qué DTD usar cuando analice un elemento dado. Es decir, que para una etiqueta se especifica que DTD usar, por lo que esto sólo tiene sentido si se usa más de un DTD. Por ejemplo, supongamos que tenemos una hoja xml con libros y otra con discos (con sus correspondientes DTD) y queremos mezclar ambas páginas. Habrá elementos que no se llamen igual (páginas o tiempo), pero otros que si (titulo, autor). Entonces se usarían ambos DTD y utilizaríamos los espacios de nombre para distinguir aquellos elementos en los que no esté claro a que DTD pertenecen.
Aunque el motivo de la especificación de los espacios de nombres fue usar más de un DTD, en la realidad ninguna herramienta soporta más de un DTD (yo, al menos, no he visto ninguna), por lo que sólo se utilizan los prefijos de espacios de nombres (que veremos dentro de poco) en XSLT(que se verá más tarde), es decir, se utilizan para distinguir las etiquetas propias de XSLT con las etiquetas del formato de salida , por ejemplo, XHTML o WML.
Los espacios de nombres se aplican tanto a atributos como a elementos. En este apartádo sólo hemos considerado elementos. Para más información sobre los atributos, puedes ver la especificación del W3C en http://www.w3.org/TR/REC-xml-names
Para definir un espacio de nombres al que pertenece un elemento, es necesario añadir un atributo a la definición de elemento, donde el nombre del atributo sea xmlns ("xml namespace") y el valor puede ser una cadena cualquiera, aunque por convención suelen ser URLs. Por ejemplo, podemos hacer esto añadiendo una entrada como la siguiente en la lista de definición de atributos de un elemento title:
<!ELEMENT title (%inline;)*> <!ATTLIST title xmlns CDATA #FIXED "http://www.ejemplos.xml/slideshow" >
Declarar el atributo como FIXED tiene varias características importantes:
Cada nombre de elemento en nuestro DTD obtendría exactamente el mismo atributo con el mismo valor.
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(tiempo y páginas en el ejemplos de los discos y de los libros). Pero cuando se usa un nombre de elemento que tiene varias definiciones, se necesita algún tipo de cualificación (nombre de disco y nombre de libro, por ejemplo).
Cualificamos una referencia a un nombre de elemento especificando el atributo xmlns, como se ve a continuación:
< title xmlns="http://www.example.com/slideshow" > Tutorial </title>
El espacio de nombres se aplica a ese elemento, y a cualquier elemento contenido dentro de él.
Usando el atributo xmls, cuando necesitamos una sóla referencia a un espacio de nombres, no es mucho trabajo, pero cuando necesitamos hacer la misma referencia varias veces, añadir dicho atributo se convierte en una tarea algo pesada. También hace dificil cambiar el nombre del espacio de nombres, en caso de que se quiera modificar posteriormente.
La alternativa es definir un prefijo de espacio de nombres, que es tan sencillo como especificar xmlns, dos puntos (:) y el nombre del prefijo antes del valor del atributo, como se ve a continuación:
<sl:slideshow xmlns:sl='http://www.example/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 raiz del documento XML.
Cuando el prefijo se usa para cualificar un nombre de elemento, la etiqueta final también incluye el prefijo, como se muestra aquí
<sl:slideshow xmlns:sl='http://www.example/slideshow' ...> ... <slide> <sl:title> Tutorial <sl:title> </slide> ... </sl:slideshow>
Finalmente podemos observar que se pueden definir varios prefijos en el mismo elemento, como se muestra a continuación
<sl:slideshow xmlns:sl='http://www.example/slideshow' xmlns:chtml="urn: ..."> ... </sl:slideshow>
Ejercicio: Veamos un ejemplo, donde se tiene información de libros en XML, pero, a su vez, se quiere usar HTML para mostrar la información:
<h:html xmlns:xdc="http://www.xml.com/books" xmlns:h="http://www.w3.org/HTML/1998/html4"> <h:head><h:title>Book Review</h:title></h:head> <h:body> <xdc:bookreview> <xdc:title>XML: A Primer</xdc:title> <h:table> <h:tr align="center"> <h:td>Author</h:td><h:td>Price</h:td> <h:td>Pages</h:td><h:td>Date</h:td></h:tr> <h:tr align="left"> <h:td><xdc:author>Simon St. Laurent</xdc:author></h:td> <h:td><xdc:price>31.98</xdc:price></h:td> <h:td><xdc:pages>352</xdc:pages></h:td> <h:td><xdc:date>1998/01</xdc:date></h:td> </h:tr> </h:table> </xdc:bookreview> </h:body> </h:html>
En el ejemplo los elementos que tiene el prefijo xdc están asociados a un espacio de nombres cuyo identificador es http://www.xml.com/books, mientras que los que tienen el prefijo h están asociados con un espacio de nombres cuyo identificador es http://www.w3.org/HTML/1998/html4.
El ejercicio tratará de hacer lo mismo que en el ejemplo anterior pero para mostrar música en MP3 en HTML. Si no sabeis como empezar, haced primero una página en XHTML y, segundo, otra siguiendo un formato de vuestra invención (por ejemplo autor, disco, fecha, estilo, etc.).