Anexo: ejercicios sobre XSLT
=====================================
Fichero origen
----------------
Para los ejercicios siguiente supondremos que se va a trabajar con el fichero que se muestra a continuación:
.. code-block:: xml
10
Ordenador
10
500
Switch
6
Generación de lista con puntos
--------------------------------
Convertir el fichero origen en una lista punteada similar a la que se muestra en la figura:
.. image:: lista_punteada.png
:align: center
:scale: 50%
.. code-block:: xml
Resultado HTML
Filtrado
----------------
Replicar la estructura del fichero pero filtrando
los elementos y haciendo que solo aparezcan los que estén
en el aula A6
Recuperación de elementos pesados
----------------------------------
Se pide un XSLT que muestre exactamente la misma información del fichero origen pero sin mostrar los elementos cuyo peso sea menor de 7.
Una posible solución sería esta:
.. code-block:: xml
Sin embargo, **dicha solución está mal** porque una pregunta básica es "el peso está en kg o en g", por lo que en realidad la condición de filtrado debe refinarse un poco más.
Supongamos entonces que el enunciado correcto pone el peso en kg. Así, la solución entonces podría hacerse de esta manera.
Productos del edificio B
----------------------------
Se pide ahora mostrar en el resultado la misma información del fichero origen pero solo en los casos en que el lugar del producto sea el edificio B
La solución es muy parecida, necesitando solamente modificar la condición.
.. code-block:: xml
Tabla de localizaciones
--------------------------
Generar una tabla HTML que muestre la información del fichero origen de la manera siguiente:
.. image:: xslt_tabla_edificio_aula.png
:align: center
:scale: 50%
.. code-block:: xml
Tablas con edificios separados
----------------------------------
Hacer una plantilla que fabrique una tabla
con los datos de los productos del edificio A
y otra tabla separada para los productos del edificio B
.. image:: xslt_tabla_edificio_separadas.png
:align: center
:scale: 50%
Una posible solución sería esta:
.. code-block:: xml
Datos por edificio
Edificio A
Edificio B
Productos del aula 6
-------------------------
Se pide generar un inventario en el que aparezcan solo los nombres de productos que estén en el aula 6.
.. code-block:: xml
Productos del edificio B
----------------------------
El siguiente ejercicio es muy parecido al anterior, con la salvedad de que ahora solo nos piden los nombres de los productos ubicados en el edificio B.
.. code-block:: xml
Condiciones múltiples: peso ligero y edificio A
-------------------------------------------------
Se pide ahora generar un fichero HTML con una tabla pero en la que solo aparezcan los productos cuyo edificio sea el A **y además** pesen menos de 7kg.
.. code-block:: xml
Resultados
|
|
Ejercicio de examen XSLT
----------------------------
Dado el siguiente fichero XML
.. code-block:: xml
Don Quijote
Cervantes
Antologia
Lorca
Miguel Hernandez
Conseguir lo siguiente:
1. Mostrar en un HTML con lista numerada los títulos de los libros con algún autor nacido despues de 1900.
.. code-block:: xml
Resultado
-
2. Mostrar en un HTML la lista de los autores ordenada por orden alfabético inverso.
.. code-block:: xml
Resultado
-
3. Mostrar el nombre de los autores nacidos despues del año 1700.
.. code-block:: xml
Resultado
Transformación de un XML bancario
--------------------------------------------------------------------
Una empresa utiliza el siguiente XML para intercambiar información entre bases de datos de distintos proveedores. Sin embargo han comprado un nuevo sistema que necesita que la información tenga una estructura siguiente. Los dos listados que se ven a continuación ilustran la estructura original y la nueva estructura que deben tener los datos. Crear el XSLT que permita convertir la información original en un formato que pueda entender el nuevo sistema.
.. code-block:: xml
Ramon Perez
12000
13-abril-2012
20-A
20000
Euros
21-DX
4800
Dolares
Carmen Diaz
1900
15-febrero-2011
.. code-block:: xml
13-abril-2012
Ramon Perez
12000 euros
15-febrero-2011
Carmen Diaz
1900 euros
20000
Euros
4800
Dolares
Análisis del problema
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Es necesario hacer varios cambios:
1. Se ha cambiado el nombre de elemento raíz de ``listado`` a ``datos``.
2. Ahora todos los elementos ``cuenta`` van dentro de un nuevo elemento ``cuentas`` y todos los elementos ``fondo`` van dentro de un nuevo elemento ``fondos``.
3. El ``dni`` se ha movido del elemento ``titular`` al elemento ``cuenta``.
4. La ``fechacreación`` se ha movido y se ha renombrado a ``creacion``.
5. El elememento ``moneda`` desaparece y su texto se ha puesto al lado de la cantidad que hay en ``saldoactual``.
6. En el elemento ``fondo`` se ha quitado el elemento ``datos``.
7. El elemento ``cuentaasociada`` ha pasado a ser un atributo.
Solución paso a paso
~~~~~~~~~~~~~~~~~~~~~~
Empecemos por crear una hoja muy básica, que busque el elemento raíz y devuelva como salida el elemento ``datos`` (que va a ser la nueva raíz)
.. code-block:: xml
Si probamos dicho XSLT aplicándolo al XML original obtendremos esto:
.. code-block:: xml
No pasa nada porque se obtenga el elemento raíz vacío, el programa de transformación lo hace para ahorrar tiempo y bytes.
Una vez que hemos cambiado el elemento raíz tenemos que generar dos elementos más que agrupen los elementos ``cuenta`` y los elementos ``fondo``. Para ello, basta con escribirlos como muestra la siguiente hoja de estilo.
.. code-block:: xml
Ahora tenemos que ir buscando todos los elementos ``cuenta`` y meterlos dentro de ``cuentas``. Despues resolveremos el problema de los fondos. Para recorrer elementos necesitamos un bucle ``for-each``. Como la plantilla ya nos ha situado en la raíz necesitaremos que el bucle nos vaya dando cada uno de los elementos ``listado/cuenta``. Es decir, le pedimos al bucle que se meta en el elemento hijo ``listado`` y nos vaya dando cada uno de los elementos ``cuenta`` que hay dentro. Un posible bucle sería este:
.. code-block:: xml
Que al pasárselo a nuestros datos nos da esto:
.. code-block:: xml
Como puede verse, la plantilla genera dos elementos ``cuenta``, uno por cada ``cuenta`` que nos da el bucle. Obsérvese que podríamos haber hecho esto para tener un nombre de elemento distinto, **y este es el "truco" para poder cambiar de nombre un elemento** :
.. code-block:: xml
Sigamos con el problema original: ya hemos creado un elemento ``cuentas`` que lleva dentro un elemento ``cuenta`` para cada una de las cuentas originales. Ahora en dicho elemento ``cuenta`` vamos a meter dentro un atributo llamado ``dnititular`` usando la etiqueta ``xsl:attribute`` que debe ir **dentro del elemento al que le queramos poner el atributo y además al principio**. Si queremos varios atributos no pasa nada podemos ponerlos todos dentro del elemento pero recordando ponerlos al principio.
Así, el código siguiente nos fabrica el atributo.
.. code-block:: xml
10
Pero hay un problema, todas las cuentas tienen el ``dnititular`` a 10. Necesitamos la etiqueta ``value-of`` que nos permite **extraer el contenido de un elemento o atributo**, en este caso queremos extrar el valor del atributo ``dni`` que está dentro del elemento ``titular``. Esto se hace con ``titular/@dni`` que significa "extraer el atributo dni que debe estar dentro del elemento titular".
Así, el código siguiente:
.. code-block:: xml
Nos devuelve como resultado:
.. code-block:: xml
El paso siguiente va a ser crear el elemento ``titular`` que también se llama ``titular`` en el archivo original. Para ello lo metemos dentro de ``cuenta`` y permitiendo que la creación del atributo ``dnititular`` se quede al principio.
El código XSLT es este
.. code-block:: xml
Que genera el siguiente resultado:
.. code-block:: xml
Ramon Perez
Carmen Diaz
Ahora vamos a crear el elemento ``saldoactual``. Dentro de ese elemento debemos escribir el texto que ya tuviese el ``saldoactual`` antiguo y escribiendo al lado el atributo ``moneda``.
El código necesario es este
.. code-block:: xml
Y el resultado es este:
.. code-block:: xml
Ramon Perez
12000euros
Carmen Diaz
1900euros
Por último, añadamos la fecha de creación. En el fichero original se llama ``fechacreación`` y en el fichero final se llama ``creación`` y además va como primer elemento. El XSLT sería este:
.. code-block:: xml
Que genera el resultado siguiente:
.. code-block:: xml
13-abril-2012
Ramon Perez
12000euros
15-febrero-2011
Carmen Diaz
1900euros
Con esto, la parte de las ``cuentas`` ya está hecha. Ahora queda lo siguiente
1. Hacer un elemento ``fondos`` con un bucle que vaya generando elementos ``fondo``.
2. Poner en el ``fondo`` el atributo ``cuentaasociada``.
3. Crear el elemento ``cantidaddepositada``.
4. Crear el elemento moneda.
Vamos con el paso 1 *"crear el elemento fondos"*
.. code-block:: xml
Ahora el paso 2: *poner el atributo "cuentaasociada"*. El XSLT sería así:
.. code-block:: xml
Con el XSLT siguiente conseguimos el paso 3: *"crear el elemento cantidaddepositada"*
.. code-block:: xml
Y por último el paso 4 "crear el elemento moneda". El XSLT sería algo así:
.. code-block:: xml
Si probamos el XSLT anterior veremos que efectivamente conseguimos transformar el fichero original en el fichero resultado que nos piden, que es el siguiente:
.. code-block:: xml
13-abril-2012
Ramon Perez
12000euros
15-febrero-2011
Carmen Diaz
1900euros
20000
Euros
4800
Dolares