Elementos opcionales en una DTD
En la DTD asociada a un documento XML, se pueden declarar elementos que contengan elementos opcionales. Para ello, se utiliza el operador de elección, representado por una barra vertical (|).
Operador de elección "|" (barra vertical)
EJEMPLO En el siguiente documento XML el elemento "articulo" puede contener un elemento "codigo" o un elemento "id"; obligatoriamente uno de ellos, pero no ambos:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE articulo [
<!ELEMENT articulo (codigo | id)>
<!ELEMENT codigo (#PCDATA)>
<!ELEMENT id (#PCDATA)>
]>
<articulo>
<codigo>AF-33</codigo>
</articulo>
Operador de elección "|" y operador "*"
EJEMPLO En la DTD del siguiente documento XML se indica que el elemento "articulos" puede contener varios elementos "codigo" e "id":
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE articulos [
<!ELEMENT articulos (codigo | id)*>
<!ELEMENT codigo (#PCDATA)>
<!ELEMENT id (#PCDATA)>
]>
<articulos>
<codigo>AF-32</codigo>
<id>3891</id>
<codigo>AF-50</codigo>
<codigo>AF-89</codigo>
</articulos>
Obsérvese que, con el operador "*", en este ejemplo se ha indicado que el contenido del elemento "articulos" tiene cardinalidad (0-n). Por tanto, el elemento "articulos" puede:
- Estar vacío.
- Contener un elemento "codigo".
- Contener un elemento "id".
- Contener un elemento "codigo" y un elemento "id".
- Contener un elemento "codigo" y varios elementos "id".
- Contener un elemento "id" y varios elementos "codigo".
- Contener varios elementos "codigo" y varios elementos "id".
Nótese también que, dentro del elemento "articulos" pueden aparecer elementos "codigo" e "id" en cualquier orden.
Operador de elección "|" en una secuencia de elementos
EJEMPLO En el siguiente documento XML, pueden aparecer cero o más elementos "articulo" que contengan un elemento "codigo" o un elemento "id", y obligatoriamente un elemento "nombre":
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE articulos [
<!ELEMENT articulos (articulo)*>
<!ELEMENT articulo ((codigo | id), nombre)>
<!ELEMENT codigo (#PCDATA)>
<!ELEMENT id (#PCDATA)>
<!ELEMENT nombre (#PCDATA)>
]>
<articulos>
<articulo>
<codigo>AF-47</codigo>
<nombre>Martillo</nombre>
</articulo>
<articulo>
<id>2056</id>
<nombre>Destornillador</nombre>
</articulo>
</articulos>
Secuencia de elementos en una lista de opciones
EJEMPLO En la DTD del siguiente documento XML se ha indicado que pueden aparecer cero o más elementos "localidad". En el caso de aparecer, cada uno de ellos contendrá los elementos "pais" y "ciudad", o alternativamente un elemento "codigo_postal":
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE localidades [
<!ELEMENT localidades (localidad)*>
<!ELEMENT localidad ((pais, ciudad) | codigo_postal)>
<!ELEMENT pais (#PCDATA)>
<!ELEMENT ciudad (#PCDATA)>
<!ELEMENT codigo_postal (#PCDATA)>
]>
<localidades>
<localidad>
<pais>España</pais>
<ciudad>Valencia</ciudad>
</localidad>
<localidad>
<codigo_postal>31015</codigo_postal>
</localidad>
</localidades>
#PCDATA en una lista de opciones permite contenido mixto
EJEMPLO Al utilizar el operador de elección (|) en una DTD, si una de las opciones es #PCDATA, esta debe escribirse en primer lugar:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE articulos [
<!ELEMENT articulos (#PCDATA | codigo | id)*>
<!ELEMENT codigo (#PCDATA)>
<!ELEMENT id (#PCDATA)>
]>
<articulos>
<id>8608</id>
Teclado
<codigo>AF-18</codigo>
<codigo>AF-45</codigo>
Disquetera
<id>7552</id>
<id>4602</id>
</articulos>
- Fíjese que, el elemento "articulos" de este documento, puede contener contenido mixto, es decir, texto y otros elementos.
EJEMPLO Véase, en este último ejemplo, que el elemento "provincia" puede aparecer cero o más veces, pudiendo contener contenido mixto:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE localidades [
<!ELEMENT localidades (provincia*)>
<!ELEMENT provincia (#PCDATA | ciudad | codigo_postal)*>
<!ELEMENT ciudad (#PCDATA)>
<!ELEMENT codigo_postal (#PCDATA)>
]>
<localidades>
<provincia>
Navarra
<ciudad>Estella</ciudad>
<codigo_postal>31015</codigo_postal>
<ciudad>Tafalla</ciudad>
</provincia>
<provincia>
Valencia
<codigo_postal>46520</codigo_postal>
</provincia>
</localidades>