******************* Lenguajes de marcas ******************* Existen muchísimos *lenguajes de marcas*, pero nos reduciremos a tratar básicamente: * |HTML|, cuyo estudio pospondremos hasta la :ref:`unidad dedicada `. * La dupla |SGML|/|XML|, en especial el segundo, ya que el primero sólo lo trataremos con un mero carácter introductorio para presentar el segundo. .. _sgml: |SGML| ****** Concepto ======== En un principio, los lenguajes de marcas era procedimentales en los que no hay separación entre estructura y presentación. En la década de los 70, en el seno de IBM_ se desarrolló |GML| como un lenguaje de macros para el lenguaje de marcas procedimental Script_, que permitía marcar el texto en términos de párrafos, listas, etc.\ [#]_ Esta idea de enfocarse en la descripción de la estructura cristalizó a mediados de la década siguiente con la publicación en 1986 de la norma |SGML| (`ISO 8879 `_) para la definición de lenguajes de marcas que se basa en establecer dos principios sobre el marcado: #. Debe ser declarativo, esto es, describir la estructura del documento y no establecer cómo debe procesarse. #. Debe ser inequívoco y riguroso a fin de que pueda definirse su procesamiento usando las mismas técnicas que se usan para procesar los programas. |SGML|, pues, no es un lenguaje concreto, sino un conjunto de normas para crear lenguajes de marcas descriptivos. Dicho de otra forma, es un metalenguaje. En consecuencia, todo documento |SGML| debe ir acompañado de un documento que defina sobre sus marcas: * Cómo deben ser (en principio, tienen la forma :code:``, pero puede definirse otra) * Cuáles son las marcas posibles y qué atributos pueden tener. * Si pueden omitirse. * Cuáles son las reglas para utilizar estas marcas dentro del texto. .. note:: Observe que al indicar una marca qué función cumple una parte del texto, debe poderse expresar desde dónde a donde va dicha parte. El modo predeterminado que tiene |SGML| de hacer esto es usando una etiqueta de apertura con el aspecto :code:`` y su correspondiente de cierre con el aspecto :code:``. Por ejemplo: .. code-block:: xml Este es el texto que marco Al documento que define el lenguaje se le conoce como |DTD|. Por ejemplo, ante esta definición\ [#]_: .. code-block:: dtd Un trozo del documento |SGML| podría ser: .. code-block:: xml Introducción al XML Concepto

El XML es un lenguaje de marcas descriptivo, etc...

Otro párrafo, etc. Y podría ser ése, porque: * No se ha definido que las marcas tengan un aspecto distinto al predeterminado. * Los capítulos contienen un título y una serie de secciones (al menos una). No puede omitirse la etiqueta ni al empezar ni al acabar. * Los títulos contienen texto y puede omitirse su etiqueta. Por supuesto, porque el no incluirla no lleva a equívoco. * Las secciones contienen un título y uno o más párrafos. Tampoco pueden omitirse sus etiquetas. * Los párrafos contienen texto y puede omitirse su cierre. En el ejemplo hemos hecho uso de la posible omisión de etiquetas, que siempre es opcional. El texto anterior es equivalente a este en que se prescinde de las omisiones: .. code-block:: xml Introducción al XML Concepto

El XML es un lenguaje de marcas descriptivo, etc...

Otro párrafo, etc.

Características =============== Las características fundamentales de |SGML| son las siguientes: #. Los documentos deben ser de **texto plano**, es decir, constituidos por caracteres que pueden ser escritos con un simple editor de textos. #. El marcado debe ser **descriptivo** y absolutamente independiente de cómo vaya a ser procesado. #. El marcado debe ser riguroso e **inequívoco** a fin de permitir su procesamiento posterior. .. _sgml-estructura: Partes ====== Un documento |SGML| está constituido por tres partes: .. _sgml-declaracion: **Declaración** |SGML| Una descripción de las características del documento |SGML|. Es aquí, por ejemplo, donde puede redefinirse la forma que adquirirán las marcas y que no sea la ya descrita como ````. .. _sgml-doctype: **Tipo de documento** La definición del tipo de documento, o sea, el |DTD|. Expone la gramática del lenguaje. Lo habitual es que se haga una simple declaración y la exposición se haga en archivo aparte. **Contenido**, esto es, una instancia concreta del tipo de documento, en que todo el contenido está incluido dentro de un elemento de primer nivel. Por ejemplo: .. code-block:: xml .. http://www.hipertexto.info/documentos/lenguajes_h.htm Derivados ========= Al ser |SGML| un metalenguaje, muchos lenguajes posteriores han tomado esta norma para definirse. Citaremos algunos: .. rst-class:: simple * DocBook_ es un dialecto |SGML| enfocado a la generación de documentación técnica. Tiene también una versión |XML|. Hasta 2016, por ejemplo, fue usado por el núcleo de *Linux* para generar su documentación\ [#]_. * |TEI| (`página web `_), nacido como un |SGML| para la codificación de textos en el ámbito de las humanidades. La |RAE|, por ejemplo, lo usan para `codificar parte de su base de datos `_. Las versiones recientes, no obstante, están basadas en |XML|. .. seealso:: Si tiene interés, puede leer este `interesante artículo sobre TEI `_. * |HTML|, dialecto enfocado a la publicación web, pero sólo hasta su versión **4.01**. Ya discutiremos sobre ello, cuando tratemos las :ref:`versiones de HTML `. * |XML|, que se tratará a continuación. .. _xml: |XML| ***** Introducción ============ Concepto -------- |XML| es una simplificación de |SGML| que elimina muchas de sus características más complejas, con el objeto de facilitar la creación de procesadores capaces de tratar los documentos escritos en alguno de sus dialectos. Es, pues, un subconjunto de |SGML| y, como él, un metalenguaje. Estas simplificaciones se concretan en\ [#]_: * Se define que las marcas sólo pueden expresarse del modo predeterminado, o sea, :code:`` para apertura, y :code:`` para cierre. * Toda etiqueta debe ser expresamente abierta y cerrada. * Los atributos de las marcas siempre requieren un valor y que éste se entrecomille. * Se define también una única notación para definir entidades (:code:`&nombre;`). Ya trataremos las entidades, ahora basta con saber que son la forma de definir las :ref:`marcas referenciales `. * Los nombres son sensibles al uso de mayúsculas y minúsculas. El |XML| se adoptó rápidamente hasta el punto que lenguajes de marcas |SGML| se redefinieron para cumplir con las simplificaciones impuestas por |XML|. Lenguajes --------- Aparte de |TEI| o DocBook_, ya citados al tratar |SGML|, porque se reescribieron en versión |XML|: * |XHTML| (versiones **1** y **2**), que fueron una reescritura de |HTML| para que el lenguaje cumpliera las reglas generales del |XML|. * |XSLT|, lenguaje para definir la transformación de un documento |XML| en otro distinto o, incluso, en algo que no sea |XML|. * |RSS|, un lenguaje pensado para la distribución de contenido en la web. * MathML_, un lenguaje para escribir fórmulas matemáticas. * SVG_, un lenguaje para la descripción de gráficos vectoriales. Los navegadores web modernos tienen soporte directo para él. * OpenDocument_, lenguaje |XML|, establecido como estándar, para la composición de documentos de texto, hojas de cálculo, presentaciones o gráficos vectoriales. Aplicaciones ------------ |XML| desde su aparición ha sido ampliamente adoptado, aunque también ha recibido críticas por ser considerado por algunos un lenguaje muy redundante y verborreico. Entre sus principales aplicaciones está: - La creación de **documentos semánticos estructurados**, que fue la principal razón de su creación. |TEI| es un ejemplo de ello. Sin embargo, ha perdido algo de fuelle en la creación de documentos algo más generales, en donde soluciones basadas en :ref:`lenguajes de marcas ligeros ` como Markdown_ o `ReStructured Text`_ le han comido terreno. - Como formato para el **intercambio de datos**, aunque en este campo pierde terreno frente a formatos con |JSON|. - Para el **almacenamiento** de cantidades modestas de datos estructurados. Por ejemplo, los datos de configuración de una aplicación, aunque para este caso pierde terreno frente a formatos como |YAML|. .. note:: Obsérvese que en el primer caso se trata de *marcado descriptivo orientado al documento*, mientras que en los dos segundos se trata de *marcado descriptivo orientado al dato*. |SGML| y su evolución |XML| son lenguajes de marcas y, en consecuencia, son más adecuados para lo primero, pese a lo cual |XML| gozó de gran predicamento y se usó profundamente para esos otros dos casos. La tendencia, sin embargo, paró hace tiempo y en los últimos años se suelen usar los lenguajes de serialización de datos (fundamentalmente |JSON| y |YAML|) cuando se quiere estructurar datos. Para la creación de documentos semánticos estructurados su suerte es más diversa: * pierde terreno para usos que requieren la escritura directa del usuario, ya que los *lenguajes de marcado ligero* son mucho más apropiados para esta tarea. * en cambio, sigue teniendo buena salud cuando el marcado no se escribe directamente, sino a través de una aplicación. Por ejemplo, el formato OpenDocument_, que no se escribe directamente sino a través de aplicaciones como LibreOffice_, o SVG_ que al ser un formato para gráficos vectoriales precisa que se usen aplicaciones de dibujo como Inkscape_. .. _xml-ejemplo: Ejemplo introductorio --------------------- Echemos un vistazo a :download:`este XML ` que permite gestionar los casilleros de los profesores de un centro de enseñanza: .. dropdown:: Casilleros de profesores .. literalinclude:: files/casilleros.xml :language: xml .. caution:: El documento no es un texto marcado, sino una sucesión de datos, por lo que estamos utilizando este |XML| para *marcado descriptivo orientado al dato*, o sea, justamente para algo para lo que se ajusta mejor un *lenguaje de serialización de datos*. Por lo general, a partir de ahora, todos los ejemplos de |XML| tendrán esta particularidad. Se observan en él las marcas claramente diferenciadas del contenido, pero aún nos viene demasiado grande entender los detalles del documento. Volveremos a ellos según aparezcan más adelante. Introduciremos a continuación cuál es la gramática general de los documentos |XML|, pero nos conviene de antemano saber cómo comprobar si son bien formados. Tenemos varias alternativas: .. rst-class:: simple * Un validador online como el proporcionado por `xmlvalidation.com `_. * La orden :program:`xmlstarlet`, instalable a través del paquete :deb:`xmlstarlet`:: $ xmlstarlet val -e casilleros.xml .. seealso:: Para más información sobre :program:`xmlstarlet` consulte el :ref:`epígrafe sobre validación con un DTD `. * ref:`Visual Studio Code ` es capaz de comprobar la sintaxis si se instala en él una extensión apropiada como `XML de RedHat `_. Anatomía del documento ====================== El propósito del epígrafe es radiografiar un documento |XML| sin entrar a analizar cuáles con las reglas que debe cumplir. Componentes ----------- Los documentos |XML| están constituidos por un conjunto de componentes de los que es imprescindible conocer su nombre y qué refieren: **Etiqueta** (o **marca**) Declara cuál es la función o el significado de una parte concreta del contenido. No es parte, pues, del contenido sino metainformación. Ya se ha indicado anteriormente que debe quedar inequívocamente claro cuál es el comienzo de la parte a la que afectan, para lo cual adoptan la forma :code:`` y cuál es el final, en donde adoptan la forma :code:``. **Texto** Es la información en sí del documento, desprovista de cualquier marca. Esán prohibidos los caracteres "<", ">" y "&", puesto que podrían confundir al procesador. **Elemento** Toda parte del contenido que constituye una parte diferencia del resto. Se delimita por una etiqueta de apertura y una de cierre. Por ejemplo, esto es un elemento ````: .. code-block:: xml Pepe y esto un elemento ````: .. code-block:: xml Pepe José Suárez Lantilla Inglés En el primer caso, el elemento está constituido exclusivamente por texto; mientras que en el segundo, el elemento lo constituyen varios elementos\ [#]_. **Atributo** Pares *nombre*/*valor* que sirven para caracterizar al elemento. Se incluyen dentro de la etiqueta de apertura de manera que siempre deben incluir valor y este debe estar escrito entre comillas simples o dobles. Cada elemento puede tener ninguno, uno o varios atributos. Por ejemplo, en el elemento raíz :code:`claustro`: .. code-block:: xml *centro* es un atributo. **Instrucción de procesamiento** Instruyen al procesador y no forman parte de la información del documento. Por ejemplo: .. code-block:: xml informa al navegador de cuál es la versión de |XML| usada y qué codificación de caracteres se ha usado para el texto. .. note:: El nombre de la codificación no es sensible a mayúsculas o minúsculas (véase `Character Sets `_). Por tanto, también podríamos haber escrito *utf-8*. **Comentario** Permiten hacer alguna anotación al marcado. Se abren con la secuencia :code:``. Dentro de ellos se puede escribir cualquier carácter incluidos nos no válidos como texto, excepto dos guiones seguidos: :code:`--`: .. code-block:: xml .. _xml-sec-cdata: Sección **CDATA** Sección del documento que el procesador tratará como texto en crudo en el que podrán encontrarse caracteres prohibidos. A diferencia del comentario, el contenido de una sección *CDATA* sí forma parte del contenido de la información. Su comienzo se marca con :code:``. **Entidad** Sirven para referenciar bien un carácter (que no puede escribirse directamente), bien un conjunto de carácteres a los que se ha preferido dar nombre. En el ejemplo, se han usado entidades para notas los nombres de los departamentos: .. code-block:: xml &EFI; La entidad :code:`&EFI;` está definida en archivo aparte (ya se verá cómo se hacen tal definición al tratar el :ref:`DTD `) y equivale a "*Educación Física*". Por tanto, lo anterior es equivalente a que se hubiera escrito: .. code-block:: xml Educación Física **Nodo** Término genérico pasa designar al resto de componentes: *nodo elemento*, *nodo atributo*, *nodo texto*, *nodo comentario*, etc. Excluimos a la *marca* de esta definición. .. seealso:: Por lo general, la información puede expresarse como elemento hijo o como atributo de un elemento. `Este artículo de IBM `_ establece algunos criterios para elegir entre uno u otro. Partes ------ Todo documento |XML| consta de dos partes: **Preámbulo** Se encuentran en él, habitualmente, algunas instrucciones de procesamiento y la declaración del tipo de documento (equivalente a la que :ref:`se hace en SGML `). Retomando el :ref:`ejemplo ilustrativo `: .. code-block:: xml .. note:: En nuestro ejemplo no hemos incluido esta declaración, porque hasta la próxima unidad no abordaremos la definición de una gramática particular. **Contenido** Es la información que contiene propiamente el documento junto a las marcas que lo caracterizan descriptiva o procedimentalmente. Todo el contenido debe estar incluido dentro de un elemento raíz. Retomando el :ref:`ejemplo ilustrativo `: .. code-block:: xml Antes de terminar la exposición de las partes que componen el documento, es preciso aclarar en un aspecto: |XML| es un simplificación de |SGML| y en consecuencia, es |SGML|. Dicho de otra forma: todo |XML| es un |SGML|. Tenemos la declración del tipo de documento y también el contenido, pero ¿dónde está la :ref:`declaración SGML `, que también es necesaria en un |SGML|? La respuesta es que se omite, porque `siempre es ésta `_ y, si se usa un procesador |XML| es porque nuestro |SGML| es un |XML| y no es necesario incluir tal declaración. .. _xml-jerarq: Estructura jerárquica --------------------- Tanto en |SGML| como en |XML| los elementos debes estar perfectamente anidados unos dentro de otros, esto es, dado un elemento siempre habrá un único nodo que lo contenga completamente, excepto el caso del elemento raíz que es el que abraca todo el contenido y no puede estar incluido dentro de nada. Gráficamente, podemos representar este hecho, así: .. image:: files/XML-Estructura.png Que se pueda establecer este árbol jerárquico, da pie a algunas definiciones: **Hijo** de un elemento dado: Es aquel elemento directamente contenido en él. .. image:: files/XML-Hijos.png **Descendiente** de un elemento dado: Es aquel nodo que directamente o a través de otros intermedios está contenido en él. En el ejemplo, si los hijos señalados contuvieran a su vez hijos, esto sería descendientes del elemento de referencia. **Padre** de un elemento dado: Es aquel que lo contiene directamente. .. image:: files/XML-Padre.png **Ascendiente** de un elemento dado: Es aquel que lo contiene directaente o a través de otros intermedios. En la figura anterior están remarcados en trazo más grueso los elementos ascendientes del de referencia. **Hermano** de un elemento dado: Es aquel que comparte con él el mismo padre. .. image:: files/XML-Hermanos.png Reglas generales ================ Clasificándolas según el componente al que afectan son las siguientes (se obvian las menos importantes): **Etiquetas** * Tienen la forma :code:`` en su apertura y :code:`` en su cierre:: José * En caso de que la marca abarque un elemento vacío, se puede usar la notación:: que es equivalente a:: * Toda etiqueta de apertura debe tener su correspondiente de cierre explícita. * El nombre de la etiqueta debe ser una sola parabra. Dicha palabra puede estar constituida por cualquier combinación de números y letras, pero el primer caracter debe ser siempre una letra. Se pueden usar signos de puntuación excepto las comillas simples y dobles, apostrofes, signos de acentuación, dólar, y punto y coma. Los dos puntos tienen un significado particular del que se hablará al tratar los espacios de nombres. * Los nombres de etiquetas que empiecen por :code:`xml` se reservan para un uso específico. * |XML| es sensible a mayúsculas y minúsculas (esta regla, en realidad, es aplicable a cualquier componente). **Elementos** * Todo el contenido del documento debe estar incluido dentro de un único elemento raíz. * Los elementos deben estar correctamente anidados dentro de otros, lo cual implica que el último elemento que se abrió deba ser el primero que se cierre. Estas dos reglas determinan que los elementos se organicen en una :ref:`estructura jerárquica `. **Atributos** * Tienen la forma :code:`nombre="valor"`, esto es: - El nombre del atributo. - El signo de igualdad (:code:`=`). - El valor que adopta el atributo para el elemento que caracteriza, siempre escrito entre comillas. Por ejemplo: .. code-block:: xml * Se incluyen exclusivamente dentro de la etiqueta de apertura. * Pueden obviarse atributos bien cuando tienen valor predeterminado, bien cuando es lícito que su valor quede indefinido. * En caso de que un atributo aparezca, debe forzosamente tener valor. Esto, por tanto, es inválido: .. code-block:: xml * Si un elemento se caracteriza con varios atributos, estos pueden escribirse en cualquier orden. * Para un mismo elemento no puede repetirse el atributo. Por tanto, esto es incorrecto: .. code-block:: xml **Entidades** * Se representan con un símbolo "&" antes del nombre de la entidad y un ";" después. Por ejemplo: .. code-block:: xml &INF; * Las entidades pueden ser de dos tipos: .. _xml-entity: a. **Predefinidas**: Hay cinco entidades que predefine la propia `especificación de XML `_: .. table:: :class: entidades +----------------+------------------------------------+ | Entidad | Significado | | +----------+-------------------------+ | | Carácter | Explicación | +================+==========+=========================+ | & | "&" | Et | +----------------+----------+-------------------------+ | < | "<" | Menor que | +----------------+----------+-------------------------+ | > | ">" | Mayor que | +----------------+----------+-------------------------+ | ' | "\\'" | comilla simple | +----------------+----------+-------------------------+ | " | "\\"" | comilla doble | +----------------+----------+-------------------------+ Además de estas, si se codifica en *UTF-8*, pueden usarse entidades para notas caracteres que no seamos capaces de escribir directamente con el teclado. Para ello, hay que averiguar cuál es su correspondiente código numérico `UNICODE `_ en decimal o hexadecimal y escribirlo del siguiente modo: * :code:`&#xHEX;` si el código es hexadecimal. * :code:`&#DEC;` si el código es decimal. Por ejemplo, podemos usar `esta tabla de caracteres `_ de cuatro columnas, de las cuales nos interesa la primera que es la que muestra el código del carácter; y la segunda que muestra escrito el carácter. Además, hay distintos bloques de caracteres que pueden escogerse en la lista desplegable "*go to the other block*". Así, si estuviéramos escribiendo un manual de física y quisiéramos escribir el nombre del padre del Electromagnetismo, Hans Christian |uostr|\ rsted, nos toparíamos con que hay un carácter (|uostr|) que no es propio del castellano, y en consecuencia somos incapaces de escribirlo directamente con el teclado. La estrategia para escribir este carácter mediante una entidad es el siguiente: #. Accedemos a la `pagina indicada `_. #. Escogemos el bloque preciso. Al tratarse de una lengua europea, es más que probable que se encuentre en uno de los bloques dedicados a caracteres latinos. #. Localizamos el bloque en la tabla para descubrir que es 'U+00D8'. Eso significa que el símbolo hexadecimal es "d8" y el carácter puede escribirse mediante la entidad :code:`Ø`. #. Opcionalmente, podemos ir a la parte superior anterior a la tabla donde se muestran opciones de visualización y escoger que se muestre la columna "numerical HTML encoding of the Unicode character" en hexadecimal o decimal. Nos aparecerá directamente el código :code:`Ø` o :code:`Ø`, respectivamente. Así pues, nuestro |XML| podría escribirse así: .. code-block:: xml Hans Christian Ørsted Danesa b. Definidas por el **usuario** en el documento que defina la gramática (un |DTD| por ejemplo). Es lo que se ha hecho en el :ref:`ejemplo introductorio ` para las entidades :code:`&EFI;`, :code:`&HyG;`, etc. .. _xmlns: Espacios de nombres =================== |XML| introduce un concepto novedoso que no existía en |SGML|: los **espacios de nombres** Un :dfn:`espacio de nombres` es un contenedor de nombres dentro del cual cada nombre es único. Es un concepto común a muchas ramas de la programación y también se adaptó a |XML|. Así, los elementos ```` o ```` son en |SGML| nombres de elementos sin nada especial, ya que los dos puntos (":") son un carácter válido. En cambio, en |XML| el primer elemento tiene el nombre "*integer*" dentro de un espacio de nombres representado con el prefijo "*xsd*" y el segundo el nombre "*template*" dentro de un espacio de nombres representado con "*xsl*". De esta forma, |XML| (haciendo gala de su característica de extensible) permite crear la gramática de un nuevo tipo de |XML| mezclando las gramáticas de tipos distintos de |XML|, a cada una de las cuales se le asocia un espacio de nombres diferente. Esto permite conjugar ambas gramáticas sin que exista peligro de colisión entre los nombres de las gramáticas. Por ejemplo, supongamos que tenemos definido un tipo de |XML| para poder escribir direcciones postales. Algo así: .. literalinclude:: files/direccion.xml :language: xml Ahora deseamos crear un nuevo tipo |XML| que permita incluir la dirección de los profesores. Podríamos hacerlo a través de los espacios de nombres: .. literalinclude:: files/casilleros_nsv1.xml :language: xml Lo que hacemos es declarar que el espacio de nombres asociado a la |URN| "*urn:profesores*" se notará con el prefijo "c"; y el espacio de nombres asociado a la |URN| "*urn:dirección*", con el prefijo "d". Podemos elegir el prefijo que más nos convenga en cada caso, pero no las |URN|\ s: ya que la |URN| correspondiente a cada gramática se define al crear la gramática. Lo habitual es que se usen |URL| y no |URN|\ s arbitrarias, como hemos hecho nosotros. .. note:: Tal como hemos escrito el |XML| estamos obligados a declarar el prefijo "d" para el espacio de nombres "*urn:direccion*" cada vez que aparezca un elemento dirección. Los espacios de nombres es posible definirlos en cualquier ascendiente, por lo que lo más cómodo suele ser declarar en el elemento raíz todos los espacios de nombres que pretendamos utilizar: .. code-block:: xml Para simplificar la escritura del |XML| que usa espacios de nombres existe el concepto de :dfn:`espacio de nombres predeterminado`, que es aquel cuyo prefijo es nulo: .. literalinclude:: files/casilleros_nsv2.xml :language: xml En este caso, es el espacio de nombres de "*urn:profesores*". Ahora bien, es perfectamente lícito cambiar el espacio de nombres predeterminado: al cambiarlo, tal cambio afecta al elemento y a todos sus descendientes. Por tanto, podríamos haber escrito también: .. literalinclude:: files/casilleros_nsv3.xml :language: xml en donde desaparecen por completo los prefijos, porque los espacios de nombres están juntos, pero no revueltos, esto es: dentro de elementos :code:``, sólo hay elementos de su propio espacio de nombres. .. caution:: Al no existir espacios de nombres en |SGML|, |DTD| que es el método para definir gramáticas heredado de |SGML| no permite definir espacios de nombres. Para hacer uso de ellos deberemos hacer las definiciones con :ref:`XSD ` o :ref:`Relax-NG `. .. _xml-resueltos: Ejercicios resueltos ==================== #. Escribir la versión |XML| del :ref:`primer ejercicio YAML resuelto `. .. dropdown:: Solución propuesta .. literalinclude:: files/ejxml1.recetas.xml :language: xml #. Escribir la versión |XML| del :ref:`segundo ejercicio resuelto `. .. dropdown:: Solución propuesta .. literalinclude:: files/ejxml2.cadena.xml :language: xml .. rubric:: Notas al pie .. [#] |GML|, por tanto, era de :ref:`marcado descriptivo `. Es común que un lenguaje de macros de un lenguaje procedimental defina macros para permitir el marcado descriptivo. Es exactamente lo mismo que sucede con TeX_ (procedimental) y a sus lenguajes de macros LaTeX_, `AMS-TeX`_ o `ConTeXt`_. .. [#] El DTD que ilustra la explicación es un SGML DTD de ahí que sea ligeramente diferente al que trataremos mas adelante. .. [#] Sin embargo, ha acabado usando Sphinx_, esto es, un :ref:`lenguaje de marcado ligero `, porque resulta mucho más sencillo de escribir. .. [#] Sólo se citan las concreciones más notorias. Para una relación completa puede consultar `el documento del W3C al respecto `_ .. [#] A efectos de definición de la estructura, el elemento :code:`` está constituido exclusivamente por elementos (:code:``, :code:``, etc., ya que los espacios, tabulaciones y espacios que se escriben entre los elementos constituyentes (que podríamos considerarlos como texto) carecen de significado. .. |SGML| replace:: :abbr:`SGML (Standard Generalized Markup Language)` .. |GML| replace:: :abbr:`GML (Generalized Markup Language)` .. |DTD| replace:: :abbr:`DTD (Document Type Definition)` .. |RAE| replace:: :abbr:`RAE (Real Academia Española)` .. |TEI| replace:: :abbr:`TEI (Text Encoding Initiative)` .. |XHTML| replace:: :abbr:`XHTML (eXtensible HyperText Markup Language)` .. |RSS| replace:: :abbr:`RSS (Really Simple Syndication)` .. |XSLT| replace:: :abbr:`XSLT (Extensible Stylesheet Language Transformations)` .. |URN| replace:: :abbr:`URN (Uniform Resource Name)` .. |YAML| replace:: :abbr:`YAML (YAML Ain't Markup Language)` .. _IBM: https://es.wikipedia.org/wiki/IBM .. _Script: https://en.wikipedia.org/wiki/SCRIPT_(markup) .. _TeX: https://tug.org/ .. _LaTeX: https://www.latex-project.org/ .. _AMS-TeX: https://es.wikipedia.org/wiki/AMS-LaTeX .. _ConTeXt: https://wiki.contextgarden.net/Main_Page .. _Docbook: https://docbook.org .. _Sphinx: http://www.sphinx-doc.org/en/master/ .. _MathML: https://www.w3.org/Math/ .. _OpenDocument: http://opendocumentformat.org/ .. _SVG: https://developer.mozilla.org/es/docs/Web/SVG/Tutorial .. _LibreOffice: https://www.documentfoundation.org/ .. _Inkscape: https://inkscape.org .. _reStructured Text: http://docutils.sourceforge.net/rst.html .. _Markdown: https://daringfireball.net/projects/markdown/ .. |uostr| unicode:: U+00D8 .. LATIN CAPITAL LETTER O WITH STROKE