Ir directamente al contenido de esta página
<!ELEMENT>
Cuando decimos que una página es valida lo que estamos diciendo es que su marcado es conforme con una gramática que define los elementos que componen un documento de un tipo determinado, los atributos que aceptan, los valores permitidos para tales atributos, y en definitiva todo aquello que se recoge en la DTD del lenguaje en el que hemos creado nuestro documento. Esta DTD a su vez, es otro documento —inicialmente marcado sobre la sintaxis de SGML, actualmente sobre la de XML— que conviene saber leer.
En general, cuando creamos un documento para la web hemos aprendido cuál debe ser su estructura, los elementos que se pueden emplear y su semántica, etc. ¿Pero qué ocurre si empleamos una DTD para la que no tenemos documentación? Para estos casos, saber qué significa algo a primera vista tan esotérico como lo que viene a continuación es de gran ayuda:
<!ELEMENT a %a.content;>
<!ATTLIST a
%attrs;
%focus;
charset %Charset; #IMPLIED
type %ContentType; #IMPLIED
name NMTOKEN #IMPLIED
href %URI; #IMPLIED
hreflang %LanguageCode; #IMPLIED
rel %LinkTypes; #IMPLIED
rev %LinkTypes; #IMPLIED
shape %Shape; "rect"
coords %Coords; #IMPLIED
>
Así, éste es el primero de una serie de artículos que se centrarán en cómo interpretar tales criptogramas, concretamente el que dedico a la definición de elementos de marcado.
Aunque para los ejemplos emplearé la DTD de XHTML 1.0 Strict (inglés)1, la interpretación vale para cualquier DTD, incluídas las desarrolladas para un uso fuera de la web.
Si alguien necesita más información sobre qué es una DTD, puede consultar «DTD y espacios de nombres» en la sección del curso.
La sintaxis general para declarar un elemento es la siguiente:
<!ELEMENT nombre_del_elemento (modelo_de_contenido)>
ELEMENT
es la palabra clave que indica que aquello que se incluye entre <!
y >
es la declaración de un elemento.nombre_del_elemento
es el que se quiera asignar.
Como las DTD modernas siguen la sintaxis de XML, si alguien quiere crear su propia DTD debería recordar que:
NL
y nl
, por ejemplo, serían elementos distintos,-
), guión bajo (_
), punto (.
) y dos puntos (:
) —no obstante este último signo se reserva para indicar espacios de nombres—,(modelo_de_contenido)
define qué otros elementos puede contener, en qué cantidad y en qué orden.Si alguien lee una DTD antigua, como la de HTML 4.01 (inglés), verá que entre el nombre del elemento y el modelo de contenido aparece - -
o - O
. Esto indicaba, respectivamente, si las etiquetas de apertura y cierre eran obligatorias o si la segunda era opcional. En las DTD actuales no aparece, porque en XML el cierre siempre es obligatorio.
De las tres, la parte más importante es el modelo de contenido, así que vamos a verlo más detenidamente.
En el modelo de contenido lo que se define es la naturaleza de los hijos que acepta un elemento.
EMPTY
Cuando se asigna EMPTY
a un elemento se está especificando que el mismo no puede contener hijo alguno.
En el ejemplo siguiente se especifica que el elemento meta
es un elemento vacío:
<!ELEMENT meta EMPTY>
En los lenguajes basados en XML significa que el elemento tiene el cierre />
al final. El elemento, por supuesto, podrá tener atributos.
#PCDATA
#PCDATA
es la abreviatura de parsed character data, es decir, texto plano interpretado o analizado como tal.
Para textarea
, por ejemplo, sólo se pemite que en el código aparezca un texto plano en su interior, en este caso el que aparecerá por defecto al usuario dentro de este campo:
<!ELEMENT textarea (#PCDATA)>
El elemento puede contener cualquier conjunto de caracteres, pero ningún otro elemento.
Aquí es donde empieza lo interesante. Es posible indicar los hijos que puede contener un elemento, y estos pueden ser:
Un único elemento:
<!ELEMENT ul (li)+>
Aquí, ul
sólo puede contener elemntos li
. El signo +
que aparece al lado indica el número de veces posible, pero de lo veremos un poco más abajo.
Una secuencia de elementos:
<!ELEMENT html (head, body)>
Compuesta por los elementos separados por comas, no sólo se indica qué elementos se permiten como hijos, sino en qué orden se permiten. En este caso, el elemento html
no puede contener más que un único elemento head
y un único elemento body
, y además necesariamente el primero debe preceder al segundo.
Una lista de opciones:
<!ELEMENT dl (dt|dd)+>
Separadas por la barra vertical (|
), sólo uno de los elementos puede aparecer. En el ejemplo son sólo dos, pero el número posible de opciones sólo está limitado por el deseo del autor de la DTD.
Como se ha visto en los ejemplos, en el modelo de contenido aparecen paréntesis y otros símbolos. Los paréntesis sirven para agrupar elementos o listas de elementos, y su principal finalidad es establecer a cuáles de los mismos se aplican los sufijos que indican el número de elementos permitidos, que son:
Sufijo | Significado |
---|---|
? | El elemento puede tener uno o ninguno de los hijos especificados, pero nunca más de uno |
* | El elemento puede tener cero o más de los hijos especificados |
+ | El elemento puede debe tener al menos uno de los hijos especificados, pero puede tener más |
Vamos a ver unos cuantos ejemplos.
<!ELEMENT optgroup (option)+>
optgroup
sólo puede contener elementos option
, en cualquier cantidad pero al menos uno.
<!ELEMENT dl (dt|dd)+>
El ejemplo que hemos visto antes. Lo que se está indicando es que un elemento dl
sólo puede contener un elemento dt
o un elemento dd
; no obstante, como indican los paréntesis, esta alternativa debe darse al menos una vez —al menos tiene que contener un hijo que sea dt
o dd
— pero puede darse tantas veces como sean necesarias. Es decir, una lista de definición puede tener un dt
, un dd
, o cualquier combinación y repetición de ambos.
<!ELEMENT table (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
Con este ejemplo mejor vamos paso a paso:
caption?
: El primer elemento que puede contener una tabla es éste, pero la interrogación nos indica que es opcional. En otras palabras, caption
podrían no aparecer, pero si lo hace necesariamente debe ser el primer hijo de table
.(col*|colgroup*)
: Lo siguiente que puede aparecer es cualquier número de columnas o grupos de columnas. No obstante, son excluyentes.
A diferencia de lo que hemos visto en el ejemplo de dl
, en este caso no se permite cualquier combinación de los dos elementos, sino cualquier número de uno de ellos.
Así, supongamos que tenemos una tabla con tres columnas y queremos indicar que las dos primeras forma un grupo. Indicarlo de la siguiente manera…
<colgroup>
<col />
<col />
</colgroup>
<col />
…sería erróneo, porque para ello en la DTD debería aparecer (col|colgroup)*
. La forma correcta sería:
<colgroup>
<col />
<col />
</colgroup>
<colgroup>
<col />
</colgroup>
thead?
: Siguiendo con la lista de elementos, la cabecera de la tabla puede aparecer ahora o no.tfoot?
: Igual para el pie de la tabla.(tbody+|tr+)
: Un caso similar al de las columnas. Ahora, sólo pueden aparecer o bien elementos tbody
o bien elementos tr
, pero sea del tipo que sea al menos debe aparecer uno.En los documentos XML narrativos como es XHTML es muy común que dentro de un elemento que en su mayor parte consiste texto plano se necesite insertar otros elementos. A este modelo de contenido se le denomina contenido mixto, y en una DTD solamente se puede indicar con una lista exhaustiva del contenido posible agrupada y con el sufijo *
:
<!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)*>
En realidad no es así como aparece especificado p
en la DTD de XHTML 1.0 estricto, sino así:
<!ELEMENT p %Inline;>
No obstante, lo que significa %Inline;
lo veremos en otro artículo, el que tratará de las entidades de una DTD.
ANY
Por último, por medio de ANY
se puede indicar que un elemento no es un elemento vacío, pero que no cuenta con un modelo de contenido concreto, es decir, que el elemento puede contener lo que sea.
En realidad ANY
se suele emplear para pruebas a medida que se va creando una DTD, pero es raro verlo en una ya pública.
Y por hoy, esto es todo, amigos. En el siguiente artículo de la serie trataré sobre cómo definir una lista de atributos para un elemento dado. Mientras, si alguien es muy impaciente, o quiere profundizar un poco más en el tema aquí tratado, puede consultar la sintaxis de las declaraciones de elementos de las DTD basadas en SGML —por su valor histórico— o la de las basadas en XML (inglés).