Una definición de tipo de documento ( DTD ) es un archivo de especificación que contiene un conjunto de declaraciones de marcado que definen un tipo de documento para un lenguaje de marcado de la familia SGML ( GML , SGML , XML , HTML ). El archivo de especificación DTD se puede utilizar para validar documentos.
Una DTD define los bloques de construcción válidos de un documento XML. Define la estructura del documento con una lista de elementos y atributos validados. Una DTD se puede declarar en línea dentro de un documento XML o como una referencia externa. [1]
Se está desarrollando una versión de DTD que tenga en cuenta los espacios de nombres como Parte 9 de ISO DSDL . Las DTD persisten en aplicaciones que necesitan caracteres de publicación especiales, como las Referencias de entidades de caracteres XML y HTML , que derivan de conjuntos más grandes definidos como parte del esfuerzo del estándar ISO SGML . XML utiliza un subconjunto de DTD SGML .
A partir de 2009 [actualizar], los lenguajes de esquema más nuevos que reconocen espacios de nombres XML (como W3C XML Schema e ISO RELAX NG ) han reemplazado en gran medida a los DTD como una mejor manera de validar la estructura XML.
Un DTD se asocia a un documento XML o SGML mediante una declaración de tipo de documento (DOCTYPE). El DOCTYPE aparece en el fragmento sintáctico doctypedecl cerca del comienzo de un documento XML. [2] La declaración establece que el documento es una instancia del tipo definido por el DTD al que se hace referencia.
Los DOCTYPE realizan dos tipos de declaraciones:
Las declaraciones del subconjunto interno forman parte del DOCTYPE en el documento mismo. Las declaraciones del subconjunto externo se encuentran en un archivo de texto independiente. Se puede hacer referencia al subconjunto externo mediante un identificador público o un identificador del sistema . Es posible que no sea necesario que los programas de lectura de documentos lean el subconjunto externo.
Cualquier documento SGML o XML válido que haga referencia a un subconjunto externo en su DTD, o cuyo cuerpo contenga referencias a entidades externas analizadas declaradas en su DTD (incluidas aquellas declaradas dentro de su subconjunto interno ), solo puede analizarse parcialmente, pero no puede validarse completamente mediante analizadores SGML o XML de validación en su modo independiente (esto significa que estos analizadores de validación no intentan recuperar estas entidades externas y su texto de reemplazo no es accesible).
Sin embargo, estos documentos todavía se pueden analizar completamente en el modo no autónomo de los analizadores de validación, lo que indica un error si no puede localizar estas entidades externas con su identificador público (FPI) o identificador del sistema (URI) especificado, o si son inaccesibles. (Las anotaciones declaradas en el DTD también hacen referencia a entidades externas, pero estas entidades no analizadas no son necesarias para la validación de documentos en el modo autónomo de estos analizadores: la validación de todas las entidades externas a las que hacen referencia las notaciones se deja a la aplicación que utiliza el analizador SGML o XML). Los analizadores no validadores pueden intentar eventualmente localizar estas entidades externas en el modo no autónomo (interpretando parcialmente el DTD solo para resolver sus entidades analizables declaradas), pero no validan el modelo de contenido de estos documentos.
El siguiente ejemplo de un DOCTYPE contiene identificadores públicos y del sistema:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//ES" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
Todos los documentos HTML 4.01 cumplen con una de las tres DTD de SGML. Los identificadores públicos de estas DTD son constantes y son los siguientes:
-//W3C//DTD HTML 4.01//EN
-//W3C//DTD HTML 4.01 Transitional//EN
-//W3C//DTD HTML 4.01 Frameset//EN
Los identificadores de sistema de estos DTD, si están presentes en el DOCTYPE, son referencias URI . Un identificador de sistema generalmente apunta a un conjunto específico de declaraciones en una ubicación resoluble. SGML permite asignar identificadores públicos a identificadores de sistema en catálogos que están disponibles opcionalmente para los solucionadores URI utilizados por el software de análisis de documentos .
Este DOCTYPE solo puede aparecer después de la declaración XML opcional y antes del cuerpo del documento, si la sintaxis del documento cumple con XML. Esto incluye los documentos XHTML :
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- el cuerpo del documento XHTML comienza aquí--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
También se puede proporcionar un subconjunto interno adicional después del subconjunto externo:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ <!-- se puede incrustar un subconjunto interno aquí -->]><!-- el cuerpo del documento XHTML comienza aquí--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
Alternativamente, sólo se puede proporcionar el subconjunto interno:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html [ <!-- se puede incrustar un subconjunto interno aquí -->]><!-- el cuerpo del documento XHTML comienza aquí--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
Finalmente, la definición del tipo de documento puede no incluir ningún subconjunto; en ese caso, simplemente especifica que el documento tiene un único elemento de nivel superior (este es un requisito implícito para todos los documentos XML y HTML válidos, pero no para fragmentos de documentos o para todos los documentos SGML, cuyos elementos de nivel superior pueden ser diferentes del elemento raíz implícito), e indica el nombre del tipo del elemento raíz:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <!-- el cuerpo del documento XHTML comienza aquí--> <html xmlns= "http://www.w3.org/1999/xhtml" > ... </html>
Las DTD describen la estructura de una clase de documentos mediante declaraciones de elementos y listas de atributos. Las declaraciones de elementos nombran el conjunto de elementos permitidos dentro del documento y especifican si los elementos declarados y las series de datos de caracteres pueden estar contenidos dentro de cada elemento y de qué manera. Las declaraciones de listas de atributos nombran el conjunto de atributos permitidos para cada elemento declarado, incluido el tipo de cada valor de atributo, si no es un conjunto explícito de valores válidos.
Las declaraciones de marcado DTD declaran qué tipos de elementos, listas de atributos, entidades y notaciones están permitidas en la estructura de la clase correspondiente de documentos XML. [3]
Una declaración de tipo de elemento define un elemento y su posible contenido. Un documento XML válido contiene únicamente elementos definidos en la DTD.
Varias palabras clave y caracteres especifican el contenido de un elemento:
EMPTY
para especificar que el elemento definido no permite contenido, es decir, no puede tener ningún elemento hijo, ni siquiera elementos de texto (si hay espacios en blanco, se ignoran);ANY
para especificar que el elemento definido permite cualquier contenido, sin restricción, es decir, que puede tener cualquier número (incluso ninguno) y tipo de elementos secundarios (incluidos elementos de texto);( #PCDATA )
:históricamente significa datos de caracteres analizados , lo que significa que solo se permite un elemento de texto en el contenido (no se permite ningún cuantificador);( #PCDATA | ''element name'' | ... )*
:se puede utilizar una selección limitada (en una lista exclusiva entre paréntesis y separada por |
caracteres de barra vertical " " y terminada con el *
cuantificador " " requerido) de dos o más elementos secundarios (incluidos solo elementos de texto o los elementos nombrados especificados) en cualquier orden y número de ocurrencias en el contenido.,
carácter de coma " ") de una o más partículas de contenido : todas las partículas de contenido deben aparecer sucesivamente como hijos directos en el contenido del elemento definido, en la posición especificada y en el orden relativo;|
carácter de barra vertical " ") de dos o más partículas de contenido : solo una de estas partículas de contenido puede aparecer en el contenido del elemento definido en la misma posición.+
para especificar que debe haber una o más ocurrencias del elemento — el contenido efectivo de cada ocurrencia puede ser diferente;*
para especificar que se permite cualquier número (cero o más) de ocurrencias: el elemento es opcional y el contenido efectivo de cada ocurrencia puede ser diferente;?
para especificar que no debe haber más de una ocurrencia: el elemento es opcional;Por ejemplo:
<!ELEMENT html ( cabeza , cuerpo ) > <!ELEMENT p ( #PCDATA | p | ul | dl | tabla | h1 | h2 | h3 )* >
Las declaraciones de tipo de elemento son ignoradas por los analizadores SGML y XML no validadores (en cuyos casos, se aceptan todos los elementos en cualquier orden y en cualquier número de ocurrencias en el documento analizado), pero estas declaraciones aún se verifican en cuanto a su forma y validez.
Una lista de atributos especifica, para un tipo de elemento determinado, la lista de todos los atributos posibles asociados a ese tipo. Para cada atributo posible, contiene:
Por ejemplo:
<!ATTLIST img src CDATA #REQUERIDO id ID #IMPLÍCITO sort CDATA #FIXED "true" print ( yes | no ) "yes" >
A continuación se muestran algunos tipos de atributos compatibles con SGML y XML:
CDATA
ID
xml:id
con este tipo, sin necesidad de ninguna declaración en el DTD, por lo que la restricción de unicidad también se aplica a estos identificadores definidos cuando se especifican en cualquier parte de un documento XML.IDREF
oIDREFS
ID
en el DTD (o el elemento único definido en un documento XML con un pseudoatributo " xml:id
") y cuyo valor efectivo sea el mismo identificador;NMTOKEN
oNMTOKENS
ENTITY
oENTITIES
(value1|...)
|
carácter de barra vertical " ") de valores textuales, donde cada valor en la enumeración posiblemente se especifica entre comillas '
simples '
o "
dobles "
si no es un token de nombre simple;NOTATION (notation1|...)
|
carácter de barra vertical " ") de nombres de notación, donde cada nombre de notación en la enumeración también debe declararse en la declaración del tipo de documento; este tipo no es compatible con los analizadores HTML, pero es válido en SGML y XML 1.0 o 1.1 (incluidos XHTML y SVG).Un valor predeterminado puede definir si un atributo debe aparecer ( #REQUIRED
) o no ( #IMPLIED
), o si tiene un valor fijo ( #FIXED
), o qué valor debe usarse como valor predeterminado ("…") en caso de que el atributo dado se omita en una etiqueta XML.
Las declaraciones de listas de atributos son ignoradas por los analizadores SGML y XML no validadores (en cuyo caso se acepta cualquier atributo dentro de todos los elementos del documento analizado), pero estas declaraciones aún se verifican para verificar su correcta formación y validez.
Una entidad es similar a una macro . La declaración de entidad le asigna un valor que se conserva a lo largo del documento. Un uso común es tener un nombre más reconocible que una referencia de carácter numérico para un carácter desconocido. [5] Las entidades ayudan a mejorar la legibilidad de un texto XML. En general, hay dos tipos: internas y externas.
Un ejemplo de declaraciones de entidad interna (aquí en un subconjunto DTD interno de un documento SGML) es:
<!DOCTYPE sgml [ <!ELEMENT sgml ANY > <!ENTITY % std "standard SGML" > <!ENTITY % signature " — &author;." > <!ENTITY % question "¿Por qué no pude publicar mis libros directamente en %std;?" > <!ENTITY % author "William Shakespeare" > ]>
<sgml> &pregunta;&firma; </sgml>
Las entidades internas pueden definirse en cualquier orden, siempre que no se haga referencia a ellas ni se analicen en la DTD o en el cuerpo del documento, en su orden de análisis: es válido incluir una referencia a una entidad aún no definida dentro del contenido de una entidad analizada, pero no es válido incluir en ningún otro lugar una referencia a una entidad nombrada antes de que esta entidad haya sido completamente definida, incluidas todas las demás entidades internas a las que se hace referencia en su contenido definido (esto también evita las definiciones circulares o recursivas de entidades internas). Este documento se analiza como si fuera:
<!DOCTYPE sgml [ <!ELEMENT sgml ANY > <!ENTITY % std "SGML estándar" > <!ENTITY % signature " — &author;." > <!ENTITY % question "¿Por qué no puedo publicar mis libros directamente en SGML estándar?" > <!ENTITY % author "William Shakespeare" > ]>
<sgml> ¿Por qué no pude publicar mis libros directamente en SGML estándar? — William Shakespeare . </sgml>
La referencia a la entidad interna "autor" no se sustituye en el texto de reemplazo de la entidad interna "firma". En cambio, se reemplaza solo cuando la referencia a la entidad "firma" se analiza dentro del contenido del elemento "sgml", pero solo mediante analizadores de validación (los analizadores no de validación no sustituyen las referencias a entidades que aparecen dentro del contenido del elemento o dentro de los valores de los atributos, en el cuerpo del documento).
Esto es posible porque el texto de reemplazo especificado en las definiciones de entidad interna permite una distinción entre referencias de entidad de parámetro (que se introducen con el carácter "%" y cuyo reemplazo se aplica al contenido de DTD analizado) y referencias de entidad generales (que se introducen con el carácter "&" y cuyo reemplazo se retrasa hasta que se analizan y validan de manera efectiva). El carácter "%" para introducir referencias de entidad de parámetro en el DTD pierde su función especial fuera del DTD y se convierte en un carácter literal.
Sin embargo, las referencias a entidades de caracteres predefinidas se sustituyen dondequiera que aparezcan, sin necesidad de un analizador validador (sólo se introducen mediante el carácter "&").
Las notaciones se utilizan en SGML o XML. Proporcionan una referencia completa a entidades externas no analizadas cuya interpretación se deja en manos de la aplicación (que las interpreta directamente o recupera la entidad externa por sí misma), asignándoles un nombre simple, que se puede utilizar en el cuerpo del documento. Por ejemplo, las notaciones se pueden utilizar para hacer referencia a datos que no son XML en un documento XML 1.1. Por ejemplo, para anotar imágenes SVG y asociarlas con un renderizador específico:
<!NOTACIÓN tipo-imagen-svg SISTEMA "imagen/svg" >
Esto declara el TEXTO de las imágenes externas con este tipo y lo asocia con un nombre de notación "type-image-svg". Sin embargo, los nombres de notación generalmente siguen una convención de nomenclatura que es específica de la aplicación que genera o utiliza la notación: las notaciones se interpretan como metadatos adicionales cuyo contenido efectivo es una entidad externa y una FPI PÚBLICA, registrada en los catálogos utilizados por los analizadores XML o SGML, o una URI del SISTEMA, cuya interpretación depende de la aplicación (aquí un tipo MIME, interpretado como una URI relativa, pero podría ser una URI absoluta para un renderizador específico, o una URN que indica un identificador de objeto específico del sistema operativo, como un UUID).
El nombre de notación declarado debe ser único dentro de toda la declaración de tipo de documento, es decir, tanto en el subconjunto externo como en el subconjunto interno, al menos para cumplir con XML. [6] [7]
Las notaciones se pueden asociar a entidades externas no analizadas incluidas en el cuerpo del documento SGML o XML. El parámetro PUBLIC
o SYSTEM
de estas entidades externas especifica el FPI y/o el URI donde se encuentran los datos no analizados de la entidad externa, y el NDATA
parámetro adicional de estas entidades definidas especifica la notación adicional (es decir, efectivamente el tipo MIME aquí). Por ejemplo:
<!DOCTYPE sgml [ <!ELEMENT sgml ( img )* > <!ELEMENTO img VACÍO > <!ATTLIST img datos ENTIDAD #IMPLIED > <!ENTIDAD ejemplo1SVG SISTEMA "ejemplo1.svg" NDATA ejemplo1SVG-rdf > <!NOTACIÓN ejemplo1SVG-rdf SISTEMA "ejemplo1.svg.rdf" > ]>
<sgml> <img data= "ejemplo1SVG" /> </sgml>
Dentro del cuerpo del documento SGML, estas entidades externas referenciadas (cuyo nombre se especifica entre "&" y ";") no se reemplazan como las entidades nombradas usuales (definidas con un valor CDATA), sino que se dejan como tokens distintos sin analizar que se pueden usar como el valor de un atributo de elemento (como arriba) o dentro del contenido del elemento, siempre que el DTD permita dichas entidades externas en el tipo de contenido declarado de los elementos o en el tipo declarado de atributos (aquí el ENTITY
tipo del data
atributo), o el analizador SGML no esté validando el contenido.
Las notaciones también pueden asociarse directamente a los elementos como metadatos adicionales, sin asociarlos a otra entidad externa, dando sus nombres como posibles valores de algunos atributos adicionales (también declarados en el DTD dentro de la declaración del elemento). Por ejemplo:<!ATTLIST ...>
<!DOCTYPE sgml [ <!ELEMENT sgml ( img )* > <!-- el valor del atributo "type" opcional solo se puede establecer en esta notación. --> <!ATTLIST sgml type NOTATION ( type-vendor-specific ) #IMPLIED > <!ELEMENT img ANY > <!-- el contenido opcional solo puede ser datos SGML o XML analizables --> <!-- el valor del atributo "title" opcional debe poder analizarse como texto. El valor del atributo "data" opcional se establece en una entidad externa no analizada. El valor del atributo "type" opcional solo puede ser una de las dos notaciones. --> <!ATTLIST img title CDATA #IMPLIED data ENTITY #IMPLIED type NOTATION ( type-image-svg | type-image-gif ) #IMPLIED > <!-- Las notaciones hacen referencia a entidades externas y pueden configurarse en los atributos "type" anteriores, o deben ser referenciadas por cualquier entidad externa definida que no pueda analizarse. --> <!NOTATION type-image-svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > <!NOTATION type-image-gif PUBLIC "image/gif" > <!NOTATION type-vendor-specific PUBLIC "application/VND.specific+sgml" > <!ENTITY example1SVGTitle "Título de example1.svg" > <!-- entidad interna analizada --> <!ENTITY example1SVG SYSTEM "example1.svg" > <!-- entidad externa analizada --> <!ENTITY example1GIFTitle "Título de example1.gif" > <!-- entidad interna analizada --> <!ENTITY example1GIF SYSTEM "example1.gif" NDATA type-image-gif > <!-- entidad externa no analizada --> ]>
<sgml type= "type-vendor-specific" > <!-- una imagen SVG se puede analizar como texto SGML o XML válido --> <img title= "&example1SVGTitle;" type= "type-image-svg" > &example1SVG; </img> <!-- también se puede hacer referencia a ella como una entidad externa no analizada --> <img title= "&example1SVGTitle;" data= "example1SVG" /> <!-- una imagen GIF no se puede analizar y solo se puede referenciar como una entidad externa --> <img title= "&example1GIFTitle;" data= "example1GIF" /> </sgml>
El ejemplo anterior muestra una notación denominada "type-image-svg" que hace referencia al FPI público estándar y al identificador del sistema (el URI estándar) de un documento SVG 1.1, en lugar de especificar solo un identificador del sistema como en el primer ejemplo (que era un URI relativo interpretado localmente como un tipo MIME). Se hace referencia a esta anotación directamente dentro del atributo "type" no analizado del elemento "img", pero no se recupera su contenido. También declara otra notación para una aplicación específica del proveedor, para anotar el elemento raíz "sgml" en el documento. En ambos casos, la notación declarada nombrada se utiliza directamente en un atributo "type" declarado, cuyo contenido se especifica en el DTD con el tipo de atributo "NOTATION" (este atributo "type" se declara para el elemento "sgml", así como para el elemento "img").
Sin embargo, el atributo "title" del elemento "img" especifica la entidad interna "example1SVGTitle" cuya declaración no define una anotación, por lo que es analizada por analizadores de validación y el texto de reemplazo de entidad es "Título de example1.svg".
El contenido del elemento "img" hace referencia a otra entidad externa "example1SVG" cuya declaración tampoco define una notación, por lo que también es analizada por analizadores de validación y el texto de reemplazo de la entidad se encuentra por su identificador SYSTEM definido "example1.svg" (también interpretado como un URI relativo). El contenido efectivo para el elemento "img" es el contenido de este segundo recurso externo. La diferencia con la imagen GIF es que la imagen SVG se analiza dentro del documento SGML, de acuerdo con las declaraciones en el DTD, donde la imagen GIF solo se referencia como un objeto externo opaco (que no se puede analizar con SGML) a través de su atributo "data" (cuyo tipo de valor es una ENTIDAD opaca).
Solo se puede especificar un nombre de notación en el valor de los atributos ENTITY (no existe soporte en SGML, XML 1.0 o XML 1.1 para múltiples nombres de notación en la misma ENTIDAD externa declarada, por lo que se necesitan atributos separados). Sin embargo, se puede hacer referencia a múltiples entidades externas (en una lista de nombres separados por espacios) en atributos declarados con el tipo ENTITIES, y donde cada entidad externa nombrada también se declara con su propia notación).
Las notaciones también son completamente opacas para los analizadores XML y SGML, por lo que no se diferencian por el tipo de entidad externa a la que pueden referenciar (para estos analizadores solo tienen un nombre único asociado a un identificador público (un FPI) y/o un identificador de sistema (un URI)).
Algunas aplicaciones (pero no los analizadores XML o SGML) también permiten hacer referencias a notaciones indirectamente nombrándolas en el "URN:''name''"
valor de un atributo CDATA estándar, en cualquier lugar donde se pueda especificar un URI. Sin embargo, este comportamiento es específico de la aplicación y requiere que la aplicación mantenga un catálogo de URN conocidos para resolverlos en las notaciones que se han analizado en un analizador SGML o XML estándar. Este uso permite que las notaciones se definan solo en un DTD almacenado como una entidad externa y se haga referencia a él solo como el subconjunto externo de documentos, y permite que estos documentos sigan siendo compatibles con los analizadores XML o SGML de validación que no tienen soporte directo para notaciones.
Las notaciones no se utilizan en HTML ni en los perfiles básicos para XHTML y SVG porque:
Incluso en la validación de analizadores SGML o XML 1.0 o XML 1.1, las entidades externas a las que hace referencia un FPI y/o URI en notaciones declaradas no son recuperadas automáticamente por los propios analizadores. En su lugar, estos analizadores simplemente proporcionan a la aplicación el FPI y/o URI analizado asociado a las notaciones encontradas en el documento SGML o XML analizado, y con una función para un diccionario que contiene todos los nombres de notación declarados en el DTD; estos analizadores de validación también verifican la unicidad de las declaraciones de nombres de notación e informan un error de validación si algunos nombres de notación se utilizan en cualquier parte del DTD o en el cuerpo del documento pero no se declaran:
La sintaxis DTD de XML es una de las muchas que existen en los lenguajes de esquemas XML . Sin embargo, muchos de ellos no reemplazan por completo a la DTD de XML. En particular, la DTD de XML permite definir entidades y notaciones que no tienen equivalentes directos en XML sin DTD (porque las entidades internas y las entidades externas analizables no forman parte de los lenguajes de esquemas XML y porque otras entidades y notaciones externas no analizables no tienen asignaciones equivalentes simples en la mayoría de los lenguajes de esquemas XML).
La mayoría de los lenguajes de esquema XML son solo reemplazos para declaraciones de elementos y declaraciones de listas de atributos, de tal manera que se hace posible analizar documentos XML con analizadores XML no validadores (si el único propósito del subconjunto DTD externo era definir el esquema). Además, los documentos para estos lenguajes de esquema XML deben analizarse por separado, por lo que validar el esquema de documentos XML en modo independiente puro no es realmente posible con estos lenguajes: la declaración del tipo de documento sigue siendo necesaria para al menos identificar (con un Catálogo XML ) el esquema utilizado en el documento XML analizado y que se valida en otro lenguaje.
Un error común sostiene que un analizador XML no validador no tiene que leer las declaraciones de tipo de documento, cuando, de hecho, las declaraciones de tipo de documento aún deben escanearse para verificar la sintaxis correcta así como la validez de las declaraciones, y el analizador aún debe analizar todas las declaraciones de entidad en el subconjunto interno y sustituir los textos de reemplazo de las entidades internas que aparecen en cualquier parte de la declaración de tipo de documento o en el cuerpo del documento.
Sin embargo, un analizador no validador puede optar por no leer entidades externas analizables (incluido el subconjunto externo ) y no tiene que respetar las restricciones del modelo de contenido definidas en las declaraciones de elementos y en las declaraciones de listas de atributos.
Si el documento XML depende de entidades externas analizables (incluido el subconjunto externo especificado o las entidades externas analizables declaradas en el subconjunto interno ), debe afirmarlo standalone="no"
en su declaración XML. El DTD de validación se puede identificar mediante catálogos XML para recuperar su subconjunto externo especificado .
En el siguiente ejemplo, el documento XML se declara con standalone="no"
porque tiene un subconjunto externo en su declaración de tipo de documento:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE people_list SYSTEM "ejemplo.dtd"> <people_list />
Si la declaración de tipo de documento XML incluye cualquier identificador SYSTEM para el subconjunto externo, no se puede procesar de forma segura como independiente: se debe recuperar el URI; de lo contrario, puede haber entidades de caracteres con nombre desconocidas cuya definición puede ser necesaria para analizar correctamente la sintaxis XML efectiva en el subconjunto interno o en el cuerpo del documento (el análisis de la sintaxis XML normalmente se realiza después de la sustitución de todas las entidades con nombre, excluyendo las cinco entidades que están predefinidas en XML y que se sustituyen implícitamente después de analizar el documento XML en tokens léxicos). Si solo incluye cualquier identificador PUBLIC, se puede procesar como independiente, si el procesador XML conoce este identificador PUBLIC en su catálogo local desde donde puede recuperar una entidad DTD asociada.
Un ejemplo de una DTD XML externa muy simple para describir el esquema de una lista de personas podría consistir en:
<!ELEMENT people_list ( persona )* > <!ELEMENT persona ( nombre , fecha de nacimiento ?, género ?, número de seguro social ?) > <!ELEMENT nombre ( #PCDATA ) > <!ELEMENT fecha de nacimiento ( #PCDATA ) > <!ELEMENT género ( #PCDATA ) > <!ELEMENT número de seguro social ( #PCDATA ) >
Tomando esto línea por línea:
people_list
es un nombre de elemento válido y una instancia de dicho elemento contiene cualquier cantidad de person
elementos. Esto *
indica que puede haber 0 o más person
elementos dentro del people_list
elemento.person
es un nombre de elemento válido y una instancia de dicho elemento contiene un elemento llamado name
, seguido de uno llamado birthdate
(opcional), luego gender
(también opcional) y socialsecuritynumber
(también opcional). El ?
indica que un elemento es opcional. La referencia al name
nombre del elemento no tiene ?
, por lo que un person
elemento debe contener un name
elemento.name
es un nombre de elemento válido y una instancia de dicho elemento contiene "datos de caracteres analizados" (#PCDATA).birthdate
es un nombre de elemento válido y una instancia de dicho elemento contiene datos de caracteres analizados.gender
es un nombre de elemento válido y una instancia de dicho elemento contiene datos de caracteres analizados.socialsecuritynumber
es un nombre de elemento válido y una instancia de dicho elemento contiene datos de caracteres analizados.A continuación se muestra un ejemplo de un archivo XML que utiliza y cumple con este DTD. Aquí se hace referencia al DTD como un subconjunto externo, a través del especificador SYSTEM y un URI. Se supone que podemos identificar el DTD con la referencia URI relativa "example.dtd"; el "people_list" después de "!DOCTYPE" nos indica que las etiquetas raíz, o el primer elemento definido en el DTD, se llama "people_list":
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE people_list SYSTEM "example.dtd"> <people_list> <persona> <nombre> Fred Bloggs </nombre> <fecha de nacimiento> 2008-11-27 </fecha de nacimiento> <género> Masculino </género> </persona> </people_list>
Se puede representar esto en un navegador compatible con XML (como Internet Explorer o Mozilla Firefox ) pegando y guardando el componente DTD anterior en un archivo de texto llamado example.dtd y el archivo XML en un archivo de texto con un nombre diferente, y abriendo el archivo XML con el navegador. Ambos archivos deben guardarse en el mismo directorio. Sin embargo, muchos navegadores no comprueban que un documento XML cumpla las reglas del DTD; solo se les exige que comprueben que el DTD sea sintácticamente correcto. Por razones de seguridad, también pueden optar por no leer el DTD externo.
El mismo DTD también se puede incrustar directamente en el propio documento XML como un subconjunto interno, encerrándolo entre [corchetes] en la declaración del tipo de documento, en cuyo caso el documento ya no depende de entidades externas y se puede procesar en modo independiente:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE lista_personas [ <!ELEMENT lista_personas (persona*)> <!ELEMENT persona (nombre, fecha de nacimiento?, género?, número_seguro_social?)> <!ELEMENT nombre (#PCDATA)> <!ELEMENT fecha de nacimiento (#PCDATA)> <!ELEMENT género (#PCDATA)> <!ELEMENT número_seguro_social (#PCDATA)> ]><people_list> <person> <name> Fred Bloggs </name> <birthdate> 2008-11-27 </birthdate> <gender> Masculino </gender> </person> </people_list>
Existen alternativas a las DTD (para especificar esquemas):
Se puede utilizar un DTD XML para crear un ataque de denegación de servicio (DoS) definiendo entidades anidadas que se expanden exponencialmente o enviando el analizador XML a un recurso externo que nunca regresa. [10]
Por este motivo, .NET Framework proporciona una propiedad que permite prohibir u omitir el análisis de DTD, [10] y las versiones recientes de las aplicaciones de Microsoft Office (Microsoft Office 2010 y superiores) se niegan a abrir archivos XML que contienen declaraciones DTD.