Ir directamente al contenido de esta página
<!ENTITY>
La entidades en una DTD son un mecanismo simple de reemplazo, el cual se aplica bien en el contexto del documento marcado de acuerdo a aquella, bien en el ámbito de la propia DTD. Esto nos da dos tipos de entidades, las generales —general entities—, como por ejemplo
<!ENTITY quot """>
<!ENTITY amp "&#38;">
<!ENTITY lt "&#60;">
<!ENTITY gt ">">
<!ENTITY apos "'">
y los parámetros de entidad —parameter entities—, como
<!ENTITY % coreattrs
"id ID #IMPLIED
class CDATA #IMPLIED
style %StyleSheet; #IMPLIED
title %Text; #IMPLIED"
>
Vamos a verlas por separado.
Las entidades generales se declaran en la DTD, pero la sustitución la realiza el intérprete en el documento que se ha marcado conforme a esa misma DTD.
La declaración de una entidad general puede ser
<!ENTITY nombre_de_la_entidad "literal">
o
<!ENTITY nombre_de_la_entidad SYSTEM "ruta_de_sistema">
o
<!ENTITY nombre_de_la_entidad PUBLIC "identificador_publico" "url_de_un_documento">
donde:
ENTITY
es la palabra clave con la que se indica que se está declarando una entidad.nombre_de_la_entidad
es el que se le asigna, que debe ser un nombre XML legal.literal
es la cadena de caracteres por la que se sustituirá la entidad en el documento.SYSTEM
indica que el literal por el que se ha de sustituir la entidad no se recoge en la DTD en la que se declara, sino en un documento independiente. También indica que dicho documento es un archivo externo al que se accede a través de la ruta especificada como ruta_de_sistema
.PUBLIC
indica también que el literal con el que reemplazar la entidad no se encuentra en la propia DTD, pero que se encuentra en un documento público, identificado por medio de identificador_publico
, y disponible en url_de_un_documento
.Vale, ahora intentemos clarificar todo esto viendo un ejemplo de funcionamiento.
Como sabemos, hay una serie de caracteres que si se emplean en el contenido de los elementos o los atributos de un documento XML harían que éste estuviera mal formado. El ejemplo más claro es <. La diple —así es como se llama este signo, vulgo «menor que»— se emplea para la apertura de las etiquetas de los elementos de marcado. En consecuencia, si aparece en el contenido de un documento de XHTML de esta manera:
<p>Aquí tenemos nuestra diple <, en su máximo esplendor.</p>
se consideraría el documento mal formado, porque el intérprete leería:
<p>Aquí tenemos nuestra diple ← Hmmmm, un elemento
sin su correspondiente cierre…
<, en su máximo esplendor.</p> ← ¿Un extraño elemento llamado
", en su máximo esplendor.</p"?
Para evitar esto, se define una entidad que ya hemos visto arriba:
<!ENTITY lt "&#60;">
Para invocarla, en el contenido o en un atributo de nuestro documento hay que emplear &
, seguido del nombre de la entidad, y un punto y coma. Así, cuando en nuestro documento XHTML el agente de usuario encuentra <
, sustituye la referencia por el caracter, pero no lo interpreta como tal, solucionándonos así el problema.
Otro ejemplo: el símbolo el euro, €. Si el documento que estamos marcado está codificado en UTF-8, no hay problema en emplear el caracter mismo, pero si se emplea alguna más restringida, por ejemplo la ISO-8859-1, hay un problema, puesto que en esta codificación el símbolo no existe. Afortunadamente, entre las entidades especiales de XHTML se define la entidad euro
:
<!ENTITY euro "€">
En realidad, en el documento bastaría incluir directamente el código del caracter, pero resulta más fácil recordar €
que €
. En ambos casos, nuestro navegador representa €.
Los dos últimos ejemplos son ejemplos de entidades generales definidas en la propia DTD, pero también podríamos encontrarnos una declaración así:
<!ENTITY euro PUBLIC
"-//W3C//ENTITY Euro for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/euro.ent">
En este caso —que no es real, me lo acabo de inventar— el W3C podría haber creado un documento en el que se recogiera la declaración de la entidad euro
, y al que se hace referencia por medio de un identificador y de su URL1. El agente de usuario, en este caso, al encontrar la referencia buscaría el recurso en línea para sustituirla por su contenido.
Por último, podríamos habernos encontrado algo como esto:
<!ENTITY euro SYSTEM "/entidades/euro.ent">
que significa que el agente de usuario debería buscar desde la ubicación de nuestra DTD la carpeta entidades y el archivo euro.ent2 en nuestro sistema. No obstante, como desarrolladores web, nunca vamos a encontrar una DTD cuyas entidades no aparezcan en documentos públicos.
Técnicamente, las que acabamos de ver son entidades generales interpretadas —parsed general entities—. En XML existen también las entidades generales no interpretadas —unparsed general entities—, pero para los documentos web es raro encontrarlas en las DTD. No obstante, haré meción a ellas en el contexto de las anotaciones, en el siguiente artículo de esta serie.
Los parámetros de entidad también son un mecanismo de sustitución, pero a diferencia de las entidades generales, la sustitución no se realiza en el contexto del documento marcado, sino dentro de la propia DTD.
Como vimos en el artículo relativo a la declaración de elementos, el modelo de contenido de cada elemento debe incluir los elementos que acepta como hijos. Así, por ejemplo, habría que definir:
<!ELEMENT p (#PCDATA | a | br | span | bdo | map | object | img | tt |
i | b | big | small | em | strong | dfn | code | q | samp |
kbd | var | cite | abbr | acronym | sub | sup | input |
select | textarea | label | button | ins | del | script)*>
<!ELEMENT h1 (#PCDATA | a | br | span | bdo | map | object | img | tt |
i | b | big | small | em | strong | dfn | code | q | samp |
kbd | var | cite | abbr | acronym | sub | sup | input |
select | textarea | label | button | ins | del | script)*>
<!ELEMENT h2 (#PCDATA | a | br | span | bdo | map | object | img | tt |
i | b | big | small | em | strong | dfn | code | q | samp |
kbd | var | cite | abbr | acronym | sub | sup | input |
select | textarea | label | button | ins | del | script)*>
…
Para simplificar la creación de la DTD, se puede crear un parámetro de entidad que recoja el modelo que se repite en todos los casos. La sintaxis sería muy similar a la que hemos visto para las entidades generales:
<!ENTITY % nombre_de_la_entidad "literal">
Como se ve, la única diferencia es el signo de porcentaje (%
) que se incluye antes del nombre de la entidad. En este caso el intérprete de XML lo que hace es sustituir la referencia por el literal al interpretar la DTD.
Nuesto ejemplo anterior podría simplificarse de esta manera:
<!ENTITY % Inline "(#PCDATA | a | br | span | bdo | map | object |
img | tt | i | b | big | small | em | strong | dfn |
code | q | samp | kbd | var | cite | abbr | acronym |
sub | sup | input | select | textarea | label |
button | ins | del | script)*">
<!ELEMENT p %Inline;>
<!ELEMENT h1 %Inline;>
<!ELEMENT h2 %Inline;>
…
En el ejemplo he empleado el parámetro de entidad para el modelo de contenido, pero se puede emplear para cualquier otro contenido, por ejemplo la lista de atributos:
<!ENTITY % i18n
"lang NMTOKEN #IMPLIED
xml:lang NMTOKEN #IMPLIED
dir (ltr|rtl) #IMPLIED"
>
<!ATTLIST head %i18n;
id ID #IMPLIED
profile CDATA #IMPLIED
>
Incluso, un parámetro de entidad puede contener a su vez otros parámetros de entidad:
<!ENTITY % Block "(%block; | form | %misc;)*">
Como en el caso de las entidades generales, el contenido sustitutorio del parámetro de entidad puede ser un archivo externo al que se apunta desde la DTD, tanto un archivo en el sistema:
<!ENTITY % ELEMSgenerales SYSTEM
"/entidades/elems-generales.ent">
como uno público:
<!ENTITY % HTMLlat1 PUBLIC
"-//W3C//ENTITIES Latin 1 for XHTML//EN"
"xhtml-lat1.ent">
<!--
Éste sí es un parámetro de entidad de la DTD de XHTML 1.0 Estricto
-->
No obstante, como ocurre con las entidades generales, estas líneas no son más que una declaración: para que el contenido se incluya efectivamente en la DTD es necesario referenciar el parámetro para que el intérprete haga la sustitución. Por ello, en algún sitio de la DTD debe explicitarse la referencia; la convención es hacerlo inmediatamente después de la declaración, que se hace igual que para las entidades generales, pero sustituyendo &
por %
:
<!ENTITY % HTMLlat1 PUBLIC
"-//W3C//ENTITIES Latin 1 for XHTML//EN"
"xhtml-lat1.ent">
%HTMLlat1;
Así, el código externo sí se incluye en la DTD.
Hasta aquí, las entidades. En el próximo artículo explicaré las anotaciones.