XML

3. XML#

Para la manipulación del formato XML tenemos varias estrategias y, dentro de ellas varias alternativas. Nos centraremos en tres:

  1. La carga en memoria del documento completo para la creación de su DOM y el acceso a sus elementos mediante técnicas ya analizadas en el módulo de Lenguajes de Marcas (XPath, XQuery o XSLT). Usan esta estrategia JAXP (que está incluida en JDK) o Saxon, que es más completa y tiene versión comercial.

  2. La traducción entre el XML y un modelo de objetos, tal como se hizo al tratar JSON. También hay varias alternativas: nosotros trataremos Jackson, que ya usamos para tratar JSON.

  3. El acceso a bases de datos XML como BaseX.

Para los ejemplos ilustrativos utilizaremos este XML:

claustro.xml#
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE claustro SYSTEM "claustro.dtd">

<claustro centro="IES Pepe Botella">
   <profesor id="p1">
      <apelativo>Pepe</apelativo>
      <nombre>José</nombre>
      <apellidos>Suárez Lantilla</apellidos>
      <departamento>Inglés</departamento>
   </profesor>

   <profesor id="p13">
      <apelativo>Cristina</apelativo>
      <nombre>María Cristina</nombre>
      <apellidos>Prieto Monagas</apellidos>
      <departamento>Biología y Geología</departamento>
   </profesor>

   <profesor id="p15">
      <apelativo>Manolo</apelativo>
      <nombre>Manuel</nombre>
      <apellidos>Páez Robledo</apellidos>
      <departamento>Matemáticas</departamento>
   </profesor>

   <!-- Profesor con casillero(s) adicional(es) -->

   <profesor id="p17" casillero="17 43">
      <apelativo>Lucía</apelativo>
      <nombre>Lucía</nombre>
      <apellidos>Gálvez Ruiz</apellidos>
      <departamento>Inglés</departamento>
   </profesor>

   <!-- En principio, si el casillero está vacío
        la aplicación les asigna el que indica su identificador,
        pero se puede asignar uno distinto.
    -->

   <profesor id="p28" casillero="52">
      <apelativo>Miguel Ángel</apelativo>
      <nombre>Miguel Ángel</nombre>
      <apellidos>Campos Sánchez</apellidos>
      <departamento>Historia</departamento>
   </profesor>

   <!-- Profesor sin casillero (tienen el 0) -->

   <profesor id="p81" casillero="0">
      <apelativo>Verónica</apelativo>
      <nombre>Verónica</nombre>
      <apellidos>Martín Díaz</apellidos>
      <departamento>Biología y Geología</departamento>
   </profesor>

   <!-- Profesor sustituto -->

   <profesor id="p86" sustituye="p81">
      <apelativo>Roberto</apelativo>
      <nombre>Roberto</nombre>
      <apellidos>Mínguez Torralbo</apellidos>
   </profesor>
</claustro>

que puede validarse con el siguiente DTD:

claustro.dtd#
<!ENTITY % datospers "(apelativo,nombre,apellidos)">
<!--
   id:         Identificador del profesor (formato i<N>)
   sustituye:  A quién sustituye al profesor.
   casillero:  Número de casillero asignado. Si no se especifica:
                  - En caso de profesor titular, la <N> de "id"
                  - En caso de sustituto, el casillero del titular.
               Si está vacío, el profesor no tiene asignado casillero.
-->
<!ENTITY % attrpers 
   "id        ID       #REQUIRED
    casillero CDATA    #IMPLIED
    sustituye IDREF    #IMPLIED">

<!ELEMENT claustro (profesor|asistente)+>
<!ATTLIST claustro centro CDATA #REQUIRED>
<!ELEMENT profesor (%datospers;,departamento?)>
<!ELEMENT asistente %datospers;>
<!ATTLIST profesor %attrpers;>
<!ATTLIST asistente %attrpers;>
<!ELEMENT nombre (#PCDATA)>
<!ELEMENT apellidos (#PCDATA)>
<!ELEMENT apelativo (#PCDATA)>
<!ELEMENT departamento (#PCDATA)>

Vayamos con las estrategias antes enumeradas: