Entidades de Parámetro
Igual que las entidades generales
nos permiten reutilizar datos XML en varios lugares, una
entidad de parámetro nos permite
reutilizar partes de un DTD en varios lugares.
También veremos como usar entidades de parámetro con secciones condicionales en un DTD.
Crear y Referenciar una Entidad de Parámetro
Recuerda que la versión existente de la presentación de diapositivas no pudo ser validada
porque el documento usaba etiquetas <em>, y éstas no eran parte
del DTD. En general, nos gustaría usar una variedad completa del estilo HTML en el texto
de un slide, no sólo una o dos, por eso tiene más sentido usar un DTD
existente para XHTML que define todas
las etiquetas que podriamos necesitar siempre. Una entidad de parémetro está diseñada para
este propósito.
Abrimos nuestro fichero DTD para la presentación y añadimos el texto en negrita de abajo para
definir una entidad de parámetro que referencia un fichero DTD externo:
<!ELEMENT slide (image?, title?, item*)>
<!ATTLIST slide
...
>
<!ENTITY % xhtml SYSTEM "xhtml.dtd">
%xhtml;
<!ELEMENT title ...
Aquí, usamos una etiqueta <!ENTITY> para defiir una entidad
de parémetro, igual que para una entidad general, pero usando una síntaxis algo
diferente. Hemos incluido un signo de tanto por ciento (%) antes del nombre de entidad
cuando definimos la entidad, y hemos usado el signo de tanto por ciento en lugar del
ampersand cuando lo referenciamos.
También, observamos que hay siempre dos pasos para usar una entidad de parámetro. Lo
primero es definir el nombre de la entidad. Lo segundo es referenciar el nombre de la
entidad, lo que realmente hace el trabajo de incluir la definición externa en el DTD
actual. Como la URI para una
entidad externa puede contener barras inclinadas (/) u otros caracteres que no son
válidos en un nombre XML, el paso de la definición permite que un nombre válido XML
sea asociado con un documento real. (Esta es la misma técnica usada en la definición
de espacios de nombres, y
en cualquier otro lugar que los constructores XML necesiten referenciar documentos externos.)
Notas:
- El fichero DTD referenciado por esta definición es
xhtml.dtd.
Podemos copiar este fichero a nuestro sistema o modificar el identificador
SYSTEM en la etiqueta <!ENTITY> para
que apunte a la URL correcta.
- Este fichero es un pequeño subconjunto de la especificación XHTML, modelado después
del borrador XHTML
Modularizado, que anima a dividir el DTD para XHTML en piezas de pequeño
tamaño, que pueden combinarse para crear diferentes subconjuntos XHTML para diferentes
propósitos. Cuando el trabajo sobre el borrador de XHTML modularizado haya finalizado,
esta versión del DTD debería ser reemplazada con algo mejor. Por ahora, esta versión
es suficiente para nuestros propósitos.
|
El punto bueno de usar un DTD basado en XHTML era obtener el acceso a una entidad definida
que cubre etiquetas de estilo HTML como <em> y
<b>.
<!ENTITY % inline "#PCDATA|em|b|a|img|br">
Esta entidad es un sencilla versión de aquellas denidas en el borrador XHTML Modularizado.
Define etiquetas del estilo HTML que son las que queremos usar -- enfasis, negrita, y un
par de ellas para imágenes y enlaces que podríamos usar o no en una presentación de
diapositivas. Para usar la entidad inline, hacemos los cambios en
negrita de abajo en nuestro DTD:
<!ELEMENT title (#PCDATA %inline;)*>
<!ELEMENT item (#PCDATA %inline; | item)* >
Estos cambios reemplazan el ítem #PCDATA con la entidad
inline. Es importante observar que #PCDATA
está primero en la entidad inline, y que inline
esta primero siempre que lo usamos. Esto es necesario por la definición XML de un
modelo de contenido mixto.
Para estar de acuerdo con este modelo, también tuvimos que añadir un asterisco al final
de la definición title. (En las dos siguientes secciones, veremos
que nuestra definición del elemento title realmente crea conflictos
con una versión definida en xhtml.dtd, y veremos diferentes formas
de resolver el problema).
|
Nota:
El DTD XHTML Modularizado define ambas entidades inline e
Inline, y hace algo de forma diferente. En vez de especificar
#PCDATA|em|b|a|img|br, sus definiciones son algo más como
(#PCDATA|em|b|a|img|br)*. Usando una de estas definiciones,
por lo tanto, se parece algo más a esto:
<!ELEMENT title %Inline; >
|
Secciones Condicionales
Antes de proceder con el siguiente ejercicio de programación, merece la pena mencionar
el uso de entidades de parámetro para controlar secciones condicionales.
Aunque no podemos condicionar el contenido
de un documento XML, podemos definir secciones condicionales en un DTD que serán parte
del DTD sólo si especificamos include. Por otro lado, si
especificamos ignore, la sección condicional no será incluida.
Supongamos, por ejemplo, que queremos usar versiones ligeramente diferentes de un DTD,
dependiendo de si estamos tratando el documento como un documento XML o un documento
SGML. Podríamos hacer esto con
definiciones DTD como estas:
someExternal.dtd:
<![ INCLUDE [
... XML-only definitions
]]>
<![ IGNORE [
... SGML-only definitions
]]>
... common definitions
Las secciones condicionales se presentan mediante "<![",
seguidas por la palabra clave INCLUDE o IGNORE
y otro "[". Después de esto viene el contenido de la sección
condicional, seguido por el terminador: "]]>". En este
caso, las definiciones XML son incluidas y las definiciones SGML son excluidas. Esto está
bien para documentos XML, pero no podemos usar DTD para documentos SGML. Por su puesto,
podríamos cambiar las palabras clave, pero esto sólo invertiría el problema.
La solución es usar referencias a entidades de parámetro en lugar de las palabras clave
INCLUDE e IGNORE:
someExternal.dtd:
<![ %XML; [
... XML-only definitions
]]>
<![ %SGML; [
... SGML-only definitions
]]>
... common definitions
Luego, cada documento que use el DTD puede configurar las definiciones de entidad apropiadas:
<!DOCTYPE foo SYSTEM "someExternal.dtd" [
<!ENTITY % XML "INCLUDE" >
<!ENTITY % SGML "IGNORE" >
]>
<foo>
...
</foo>
Este procedimiento da a cada documento el control del DTD. También reemplaza las palabras
clave INCLUDE e IGNORE con nombres de variables
que reflejan de forma más segura el propósito de la sección condicional, produciendo una
versión del DTD más leíble y auto-documentada.