|
El API JAXP |
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.
|
Nota:
El XML mostrado aquí está en slideshow2.dtd. El fichero XML que referencia es slideSample08.xml. |
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 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.
Me ha aclarado muchas ideas
















































