Ir directamente al contenido de esta página

codexexempla.org

Leer una DTD: <!ENTITY>

Tabla de contenidos

  1. Introducción
  2. Entidades generales
  3. Parámetros de entidad

Introducción

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 generalesgeneral entities—, como por ejemplo


    <!ENTITY quot     "&#34;"> 
    <!ENTITY amp      "&#38;#38;"> 
    <!ENTITY lt       "&#38;#60;"> 
    <!ENTITY gt       "&#62;"> 
    <!ENTITY apos     "&#39;"> 
            

y los parámetros de entidadparameter entities—, como


    <!ENTITY % coreattrs
        "id          ID             #IMPLIED
         class       CDATA          #IMPLIED
         style       %StyleSheet;   #IMPLIED
         title       %Text;         #IMPLIED"
    >
            

Vamos a verlas por separado.

Entidades generales

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:

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 "&#38;#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 &lt;, 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 "&#8364;">
            

En realidad, en el documento bastaría incluir directamente el código del caracter, pero resulta más fácil recordar &euro; que &#8364;. 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 interpretadasparsed general entities—. En XML existen también las entidades generales no interpretadasunparsed 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.

Parámetros de entidad

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.

Notas

  1. No obstante, esto habría que hacerlo para todas y cada una de las entidades; como veremos más abajo, es más efectivo incluir una lista completa de las entidades por medio de un parámetro de entidad. Volver
  2. Como para la extensión .dtd, .ent es una convención, no una exigencia de la especificación. Volver

Contacto

En virtud de la Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal le informo de que los datos que proporcione no serán empleados para otro fin que el de responder a su mensaje. En especial, me comprometo a no cederlos a terceros ni a emplearlos para enviar información no solicitada.

Del blog de Digital Icon