Práctica Número 8, Curso 2004/05, Fecha 16/12/2004

1. alumnos

A continuación se presenta un fichero XML con información sobre alumnos


<?xml version="1.0" encoding="iso-8859-1"?>
<alumnos>
  <alumno dni="9394949">
    <nombre>Marta</nombre>
    <apellidos> Palomares</apellidos>
    <nota>5</nota>
    <email>juan@petra.euitio.uniovi.es</email>
  </alumno>

  <alumno dni="9394942">
    <nombre>Kiko</nombre>
     <apellidos> Matamoros</apellidos>
    <nota>6</nota>
    <email>kiko@cronicas.org</email>
  </alumno>

  <alumno dni="9394922">
    <nombre>Leo</nombre>
     <apellidos> Amor Discos</apellidos>
    <nota>5</nota>
    <email>Amor@Discos.com</email>
  </alumno>

  <alumno dni="98765432">
    <nombre>Diana</nombre>
    <apellidos> Digo Ana</apellidos>
    <nota>8</nota>
    <email>Digo@Alumnos.com</email>
  </alumno>

  <alumno dni="9394233">
    <nombre>Elque</nombre>
    <apellidos> Suspende</apellidos>
    <nota>4.7</nota>
    <email>elque@siempre.suspende.com</email>
  </alumno>

  <alumno dni="23234454">
    <nombre>Raspa</nombre>
      <apellidos> Dillo</apellidos>
    <nota>5</nota>
    <email>ras@padillo.com</email>
  </alumno>

  <alumno dni="23233444">
    <nombre>Elque</nombre>
     <apellidos>Sacano Table</apellidos>
    <nota>8</nota>
    <email>elque@sacano.table.org</email>
  </alumno>

  <alumno dni="23231212">
    <nombre>Enrique</nombre>
     <apellidos>Quepa López</apellidos>
    <nota>9.7</nota>
    <email>Kike@alumnos.com</email>
  </alumno>

  <alumno dni="2323129">
    <nombre>Pepe</nombre>
    <apellidos> Kui Kou</apellidos>
    <nota>6</nota>
    <email>pepe@alumnos.com</email>
  </alumno>

  <alumno dni="2323100">
    <nombre>Jose</nombre>
    <apellidos>López López</apellidos>
    <nota>6</nota>
    <email>pepe@alumnos.com</email>
  </alumno>

  <alumno dni="2323101">
    <nombre>Marta</nombre>
    <apellidos>Tarma Martínez</apellidos>
    <nota>8</nota>
    <email>martama@alumnos.com</email>
  </alumno>

</alumnos>

Un ejemplo de hoja de estilos en formato XSLT podría ser:


<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" />
 

  <xsl:template match="alumnos">
    <html>
   <head>
   <title>Información de Alumnos</title>
   </head>
    <body>
      <h1>Lista de alumnos</h1>
      <ul>
       <xsl:apply-templates />
      </ul>
    </body>
    </html>
</xsl:template>

<xsl:template match="alumno">
<li><xsl:value-of select="nombre"/>
    <xsl:value-of select="apellidos"/>
</li>  
</xsl:template>

</xsl:stylesheet>

Procesar el documento XML con dicha hoja de estilos y visualizar el resultado en una página Web

Para ello se puede utilizar la utilidad xsltproc de GNOME

La instrucción sería xsltproc -o p.html alumnos.xsl alumnos.xml

Una versión simplificada de dicha utilidad puede obtenerse en http://www.di.uniovi.es/~labra/FTP/XML/xmlfacil.zip




2. Nota

Modificar la hoja de estilos para que incluya información sobre la nota de un alumno




3. mail

Modificar la hoja de estilos para que incluya información sobre el correo electrónico de cada alumno

Añadir un hiper-enlace de forma que permita enviar un correo electrónico directamente al alumno mediante <a href="mailto:correo@xxx">correo@xxx</a>




4. Tabla

Modificar la hoja de estilos para que muestre la información en formato de tabla




5. Suma

En XSLT es posible definir funciones asignando un nombre a las plantillas. El siguiente ejemplo, calcula la suma de dos números


<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" />

<xsl:template match="/">
 2+3=<xsl:call-template name="suma">
   <xsl:with-param name="a" select="2" />
   <xsl:with-param name="b" select="3" />
 </xsl:call-template>

 5+7=<xsl:call-template name="suma">
   <xsl:with-param name="a" select="5" />
   <xsl:with-param name="b" select="7" />
 </xsl:call-template>
</xsl:template>

<xsl:template name="suma">
<xsl:param name="a"/>
<xsl:param name="b"/>
 <xsl:value-of select="$a + $b"/>
</xsl:template>
    

</xsl:stylesheet>

Crear una función que tome como argumento un valor xxx y genere una expresión de la forma <a href="mailto:xxx">xxx</a>

Re-escribir la hoja de estilos de los alumnos utilizando dicha función




6. NotaTexto

Crear una función que convierta la nota numérica en nota textual, es decir, sobresaliente, notable, aprobado y suspenso

Añadir una columna a la tabla de alumnos mostrando la nota textual




7. Factorial

Crear una función que calcule el factorial de un número en XSLT




8. Map

Aunque es posible utilizar funciones de orden superior en XSLT, su uso depende de un truco descrito por Dimitre Novatchev que permite hacer una llamada a una función de forma dinámica mediante su identificación en un espacio de nombres único.

Por ejemplo, la siguiente hoja de estilos implementa la función map


<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:f1="f1"
    xmlns:f2="f2">

<!-- nodos ficticios -->
<f1:nodo/>
<f2:nodo/>

<xsl:variable name="nodof1" select="document('')//f1:*"/>
<xsl:variable name="nodof2" select="document('')//f2:*"/>

<xsl:template match="/">

 <xsl:call-template name="map">
   <xsl:with-param name="f" select="document('')//f1:*" /> 
   <xsl:with-param name="ls" select="/alumnos/alumno/nota" />
 </xsl:call-template>

<xsl:text>
</xsl:text>
 
 <xsl:call-template name="map">
   <xsl:with-param name="f" select="$nodof2" /> 
   <xsl:with-param name="ls" select="/alumnos/alumno/nota" />
 </xsl:call-template>

</xsl:template>

<xsl:template name="f1"
	      match="node()[namespace-uri()='f1']">
  <xsl:param name="x"/>
  <xsl:value-of select="$x + 1"/>
  <xsl:text> </xsl:text>
</xsl:template>


<xsl:template name="f2"
	      match="node()[namespace-uri()='f2']">
  <xsl:param name="x"/>
  <xsl:value-of select="$x * 2"/>
  <xsl:text> </xsl:text>
</xsl:template>

<xsl:template name="map">
 <xsl:param name="f" select="/*"/>
 <xsl:param name="ls" />
 
 <xsl:choose>
  <xsl:when test="$ls">
      <xsl:apply-templates select="$f">
	<xsl:with-param name="x" select="$ls[1]"/>
      </xsl:apply-templates>
      <xsl:call-template name="map">
        <xsl:with-param name="f" select="$f"/>
        <xsl:with-param name="ls" select="$ls[position()!=1]"/>
      </xsl:call-template>
   
  </xsl:when>
 </xsl:choose>

</xsl:template>

</xsl:stylesheet>

Ejecutar la hoja de estilos anterior para comprobar cómo se aplican las funciones a todas las notas

Añadir una función que divida todas las notas entre 2 y aplicar dicha función a todas las notas




9. foldr (Opcional)

Implementar la función foldr de forma similar a la función map anterior

Aplicar la función foldr para calcular la suma de todas las notas, el producto de todas las notas y el número de notas del fichero de alumnos




10. Media (Opcional)

Modificar la hoja de estilos de alumnos para incorporar al final de la tabla la nota media de las notas de todos los alumnos

Nota: Este ejercicio puede realizarse mediante la función foldr del ejercicio anterior o mediante las funciones predefinidas de XPath sum y count



11. SVG

La siguiente hoja de estilos convierte el fichero de alumnos a formato SVG


<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" 
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xlink="http://www.w3.org/1999/xlink" >

<xsl:output method="xml"  encoding="iso-8859-1" indent="yes"/>
 

  <xsl:template match="alumnos">
   <xsl:element name="svg">
    <xsl:attribute name="height"><xsl:value-of select="count(//alumno)*1.5"/>cm
    </xsl:attribute>
    <xsl:attribute name="width">18cm</xsl:attribute>
     <xsl:attribute name="viewBox">
       <xsl:text>0 0 </xsl:text>
       <xsl:value-of select="20 * 100"/><xsl:text> </xsl:text>
       <xsl:value-of select="count(//alumno)*100 + 300"/>
      </xsl:attribute>
      <desc>
	<xsl:value-of select="curso"/>
      </desc>

<defs>
<path id="linea">
    <animate attributeName="d"
    id="a1"
 from="M 100 130 L 200 110 L 300 130 L 400 110 L 500 130 L 600 110 L 700 130 L 800 110 
  L 900 130 L 1000 110 L 1100 130 L 1200 110 L 1300 130 L 1400 110 L 1500 130 
  L 1600 110 L 1700 130 L 1800 110"
 to="M 100 130 L 200 150 L 300 130 L 400 150 L 500 130 L 600 150 L 700 130 L 800 150 
     L 900 130 L 1000 150 L 1100 130 L 1200 150 L 1300 130 L 1400 150 L 1500 130 
     L 1600 150 L 1700 130 L 1800 150"
 dur="5s"
 fill="freeze"
      />
  </path>
</defs>

      <text x="50" y="80" font-family="fantasy" font-size="60">
	<textPath xlink:href="#linea">
  	   Notas del curso
	<tspan fill="blue">
                 <xsl:element name="a">
	   <xsl:attribute name="xlink:href"><xsl:value-of 
                     select="curso/@href"/></xsl:attribute>
	   <xsl:value-of select="curso"/>
	</xsl:element>
        </tspan>
        </textPath>
      </text>

      <xsl:element name="rect">
            <xsl:attribute name="x">25</xsl:attribute>
            <xsl:attribute name="y">5</xsl:attribute>
            <xsl:attribute name="rx">50</xsl:attribute>
            <xsl:attribute name="ry">50</xsl:attribute>
            <xsl:attribute name="width">1810</xsl:attribute>
            <xsl:attribute name="height"><xsl:value-of 
                  select="count(//alumno) * 100 + 260"/>
	     </xsl:attribute>
	<xsl:attribute name="stroke">blue</xsl:attribute>
	<xsl:attribute name="fill">none</xsl:attribute>
              <xsl:attribute name="stroke-width">3</xsl:attribute>
      </xsl:element>

      <xsl:element name="rect">
            <xsl:attribute name="x">40</xsl:attribute>
            <xsl:attribute name="y">20</xsl:attribute>
            <xsl:attribute name="rx">50</xsl:attribute>
            <xsl:attribute name="ry">50</xsl:attribute>
            <xsl:attribute name="width">1780</xsl:attribute>
            <xsl:attribute name="height"><xsl:value-of 
                   select="count(//alumno) * 100 + 230"/>
	     </xsl:attribute>
	<xsl:attribute name="stroke">blue</xsl:attribute>
	<xsl:attribute name="fill">none</xsl:attribute>
              <xsl:attribute name="stroke-width">3</xsl:attribute>
      </xsl:element>

     <g font-family="serif" fill="green"
           font-size="50" >
     <xsl:apply-templates select="alumno"/>
     </g>
   </xsl:element>
  </xsl:template>

 <xsl:template match="alumno">
   <xsl:element name="text">
       <xsl:attribute name="x">100</xsl:attribute>
        <xsl:attribute name="y"><xsl:value-of select="position() * 100 + 200"/>
        </xsl:attribute>
     <xsl:value-of select="@dni"/> 
   </xsl:element>

   <xsl:element name="text">
       <xsl:attribute name="x">500</xsl:attribute>
        <xsl:attribute name="y"><xsl:value-of select="position() * 100 + 200"/>
        </xsl:attribute>
      <xsl:element name="a">
     <xsl:attribute name="xlink:href">mailto:<xsl:value-of select="email"/>
     </xsl:attribute>
     <xsl:value-of select="apellidos"/>, <xsl:value-of select="nombre"/>
   </xsl:element>
   </xsl:element>

   <xsl:element name="text">
    <xsl:attribute name="x">1400</xsl:attribute>
     <xsl:attribute name="y"><xsl:value-of select="position() * 100 + 200"/>
     </xsl:attribute>
     <xsl:value-of select="nota"/> 
   </xsl:element>

</xsl:template>

</xsl:stylesheet>




12. Otros formatos (Opcional)

Trasladar el fichero de alumnos a otros formatos como WML, X3D, XSL-FO, etc.




13. Otros Vocabularios (Opcional)

Definir otros vocabularios XML con información de otro tipo y convertirlos a diversos formatos HTML, WML, X3D, XSL-FO, etc. mediante XSLT