[xsl] Shorter, better, nicer XSLT

Subject: [xsl] Shorter, better, nicer XSLT
From: Antonio Bueno <atnbueno@xxxxxxxxxx>
Date: Thu, 14 Mar 2002 23:07:26 +0100
Hello,

Some time ago I wrote a transformation to search text in Sat TV
program listings. I just wanted it to work, and it did. But I didn't
really liked how it ended. Too much almost-the-same almost-repeated
code.

The transformation searched ("buscar" in Spanish) for the text but it
also allowed to restrict the search by date ("fecha" in Spanish)
and/or channel ("canal" in Spanish).

I finally ended doing each combination separatedly
(any_date+any_channel, one_date+any_channel, any_channel+one_date and
one_date+one_channel). And repeated paths everywhere.

I've included a striped down version of the XML and the XSLT files for
reference.

Do you have any ideas to do it better? I'd appreciate any sugestion in
simplicity or performance and I'll humbly accept any reprimand on my
lack of XSLT knowledge :)

Oh, and if someone wants to see the "full version" work, you have it
at http://mundoplus.tv/programacion/buscador.asp

Thanks in advance and
greetings from Spain,
 Antonio

http://mundoplus.tv
mailto:atnbueno@xxxxxxxxxxxx


programacion.xml------------------------------------------------------

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE programacion SYSTEM "programacion.dtd">
<programacion>
  <canal id="*">Todos los canales</canal>
  <canal id="CP">Canal +</canal>
  <canal id="AXN">AXN</canal>
  <canal id="NG">National Geographic</canal>
  <fecha id="*">Todos los días</fecha>
  <fecha id="20020401">1 de abril</fecha>
  <fecha id="20020402">2 de abril</fecha>
  <fecha id="20020403">3 de abril</fecha>
 <parrilla canal="CP" dial="002" fecha="20020401">
  <evento hora="0755" tipo="D">Noticias CNN+</evento>
  <evento hora="0820">Pim, pam, plus: Looney Tunes</evento>
  <evento hora="0845">Pim, pam, plus: El guerrero samurai</evento>
  <evento hora="0910">Pim, pam, plus: Men in Black</evento>
  <evento hora="0935">Pim, pam, plus: Grandullón y Robotín</evento>
  <evento hora="1000" dolby="sí" estereo="sí" subtitulos="sí">Cine: October Sky (Cielo de
octubre)</evento>
  <evento hora="1144" dolby="sí" estereo="sí" subtitulos="sí">Cine: Doble traición</evento>
 </parrilla>
 <parrilla canal="CP" dial="002" fecha="20020402">
  <evento hora="0137">Cine: Divertimento</evento>
  <evento hora="0310">Baloncesto: Liga N.C.A.A.: Final Four (Final)</evento>
  <evento hora="0540">Cine: Mundo grúa</evento>
  <evento hora="0709">Documental: Ana y el rey: La verdadera historia de Anna
Leonowens</evento>
  <evento hora="0755" tipo="D">Noticias CNN+</evento>
  <evento hora="0820">Cuadernos de rodaje</evento>
  <evento hora="0845" tipo="M">ACB+</evento>
  <evento hora="0910" estereo="sí">Lo + Plus</evento>
  <evento hora="1000">Baloncesto: Liga N.C.A.A.: Final Four (Final)</evento>
 </parrilla>
 <parrilla canal="CP" dial="002" fecha="20020403">
  <evento hora="0131">Cine: Vía final</evento>
  <evento hora="0300">NBA</evento>
  <evento hora="0600" subtitulos="sí">Cine: La guerra de los Rose</evento>
  <evento hora="0755" tipo="D">Noticias CNN+</evento>
  <evento hora="0820">Transworld Sport</evento>
  <evento hora="0910" estereo="sí">Lo + Plus</evento>
  <evento hora="1000" subtitulos="sí">Cine: Stuart Little</evento>
  <evento hora="1122" subtitulos="sí">Cine: Cuando un hombre ama a una mujer</evento>
 </parrilla>
 <parrilla canal="AXN" dial="014" fecha="20020401">
  <evento hora="0028" estereo="sí" idiomas="VM">Absolución</evento>
  <evento hora="0201" estereo="sí">Tiempo Sincro: Episodio 21</evento>
  <evento hora="0237" estereo="sí">Código AXN: Emisión 14</evento>
  <evento hora="0300" estereo="sí" idiomas="VM">Han llegado</evento>
  <evento hora="0503" estereo="sí">Código AXN: Emisión 10</evento>
  <evento hora="0527" estereo="sí">Al filo de lo imposible: El laberinto azul. Primera
parte.</evento>
  <evento hora="0600" estereo="sí" idiomas="VM">Battle Dome: Episodio 17</evento>
  <evento hora="0700" estereo="sí" idiomas="VM">Battle Dome: Episodio 18</evento>
  <evento hora="0755" estereo="sí">Al filo de lo imposible (piloto: k2)</evento>
  <evento hora="0900">Extrememanía</evento>
  <evento hora="1000" estereo="sí">Antivicio: Órganos Vitales</evento>
  <evento hora="1130" estereo="sí" idiomas="VM">Stargate SG-1: La luz</evento>
 </parrilla>
 <parrilla canal="AXN" dial="014" fecha="20020402">
  <evento hora="0017" estereo="sí" idiomas="VM">Pasados de Vueltas: Yo, yo mismo y mi
menda</evento>
  <evento hora="0047" estereo="sí" idiomas="VM">Fuerza Máxima</evento>
  <evento hora="0224" estereo="sí" idiomas="VM">Chilli Factor: Episodio 11</evento>
  <evento hora="0300" estereo="sí">Código AXN: Emisión 29</evento>
  <evento hora="0325" estereo="sí">Al filo de lo imposible: Tierra de aventuras
(presentación)</evento>
  <evento hora="0357" estereo="sí" idiomas="VM">Helicops: Bautismo de Fuego para el
AK-1</evento>
  <evento hora="0445" estereo="sí" idiomas="VM">World Windsurf 2000: Presentación</evento>
  <evento hora="0518" tipo="E" estereo="sí" idiomas="VM">Snowboarder TV: Emisión 1</evento>
  <evento hora="0542" estereo="sí">Antivicio: El Juego de los Peones</evento>
  <evento hora="0700" estereo="sí" idiomas="VM">La ley de la Bahía: Viejos huesos</evento>
  <evento hora="0800" estereo="sí" idiomas="VM">Stargate SG-1: Prodigio</evento>
  <evento hora="0900">Extrememanía</evento>
  <evento hora="1000" estereo="sí">Caiga Quien Caiga: Emisión 25</evento>
  <evento hora="1130" estereo="sí" idiomas="VM">Stargate SG-1: Prodigio</evento>
 </parrilla>
 <parrilla canal="AXN" dial="014" fecha="20020403">
  <evento hora="0024" estereo="sí" idiomas="VM">Últimas Vidas</evento>
  <evento hora="0157" tipo="E" estereo="sí" idiomas="VM">Destino: Aventura: Episodio
12</evento>
  <evento hora="0300" estereo="sí">Código AXN: Emisión 30</evento>
  <evento hora="0325" estereo="sí">Al filo de lo imposible: En las orillas del
cielo</evento>
  <evento hora="0400" estereo="sí" idiomas="VM">Helicops: Bautismo de Fuego para el AK-1.
Segunda Parte</evento>
  <evento hora="0448" estereo="sí" idiomas="VM">World Windsurf 2000: Maui Wave
Special</evento>
  <evento hora="0530">Caiga quien caiga: Emisión 26</evento>
  <evento hora="0700">La ley de la Bahía: Fair Cop</evento>
  <evento hora="0800" estereo="sí" idiomas="VM">Stargate SG-1: El ente</evento>
  <evento hora="0900">Extrememanía</evento>
  <evento hora="1000" estereo="sí">Hospital Central: Relaciones Difíciles</evento>
  <evento hora="1130" estereo="sí" idiomas="VM">Stargate SG-1: El ente</evento>
 </parrilla>
 <parrilla canal="NG" dial="033" fecha="20020401">
  <evento hora="0030">Shock Cultural: AIDS - Supervivencia I</evento>
  <evento hora="0100">Genio National Geographic: Episodio 5</evento>
  <evento hora="0130">Seis experimentos que transformaron el mundo: Galileo: el padre de la
ciencia</evento>
  <evento hora="0200">La aventura comienza aquí: Odisea ultraliviana: Episodio 1</evento>
  <evento hora="0230">El frío y el espacio</evento>
  <evento hora="0300">Detrás de la lente: En busca de una princesa perdida</evento>
  <evento hora="0430">Shock Cultural: AIDS - Supervivencia I</evento>
  <evento hora="0500">Genio National Geographic: Episodio 5</evento>
  <evento hora="0530">Seis experimentos que transformaron el mundo: Galileo: el padre de la
ciencia</evento>
  <evento hora="0600">La aventura comienza aquí: Odisea ultraliviana: Episodio 1</evento>
  <evento hora="0630">El frío y el espacio</evento>
  <evento hora="0700">Cocodrilos a toda hora: El cocodrilo asesino de Mondonguillo</evento>
  <evento hora="0730">El festival del cocodrilo</evento>
  <evento hora="0800">Ataque! Cocodrilos</evento>
  <evento hora="0900">El último banquete de los cocodrilos</evento>
  <evento hora="1000">Gaviales a casa / El hombre de las serpientes</evento>
  <evento hora="1030">Festival de la cobra / Cueva de cocodrilos</evento>
  <evento hora="1100">Cocodrilos</evento>
  <evento hora="1130">Sacrificio en Malawi</evento>
 </parrilla>
 <parrilla canal="NG" dial="033" fecha="20020402">
  <evento hora="0000">El cocodrilo asesino de Mondonguillo</evento>
  <evento hora="0030">Las boas de Nicaragua</evento>
  <evento hora="0100">Renis da Silveira, amante de la selva</evento>
  <evento hora="0200">El último banquete de los cocodrilos</evento>
  <evento hora="0300">Lucha en Jamaica</evento>
  <evento hora="0330">Cocodrilos en Cancún</evento>
  <evento hora="0400">Cocodrilos</evento>
  <evento hora="0430">Sacrificio en Malawi</evento>
  <evento hora="0500">Los amos de los Everglades</evento>
  <evento hora="0600">Renis da Silveira, amante de la selva</evento>
  <evento hora="0700">Cocodrilos a toda hora: El último banquete de los cocodrilos</evento>
  <evento hora="0800">Asesinos en Madagascar</evento>
  <evento hora="0830">El festival del cocodrilo</evento>
  <evento hora="0900">La hora del depredador: La civeta gigante de Célebes</evento>
  <evento hora="1000">NG Classics: Ascensión en el África</evento>
  <evento hora="1030">La vida en la cuerda floja</evento>
  <evento hora="1100">Ciencia extrema: Cuevas de hielo</evento>
  <evento hora="1130">Cocodrilos</evento>
 </parrilla>
 <parrilla canal="NG" dial="033" fecha="20020403">
  <evento hora="0000">Dentro de la zona mortal: El K2 + Vuelta al K2</evento>
  <evento hora="0100">África: tierra del sol: Parque Kruger 100: la visión continúa</evento>
  <evento hora="0200">La Australia de Ben Dark: Muerte en el desierto</evento>
  <evento hora="0300">Las maravillas del mundo: Ceremonia en el monte Merón</evento>
  <evento hora="0330">Borneo: más allá de la sepultura</evento>
  <evento hora="0400">Dentro de la zona mortal: El K2 + Vuelta al K2</evento>
  <evento hora="0500">África: tierra del sol: Parque Kruger 100: la visión continúa</evento>
  <evento hora="0600">La Australia de Ben Dark: Muerte en el desierto</evento>
  <evento hora="0700">Las maravillas del mundo: Ceremonia en el monte Merón</evento>
  <evento hora="0730">Borneo: más allá de la sepultura</evento>
  <evento hora="0800">Dentro de la zona mortal: El K2 + Vuelta al K2</evento>
  <evento hora="0900">La hora del depredador: La gran serpiente</evento>
  <evento hora="1000">NG Classics: Defensores de la naturaleza en Botswana</evento>
  <evento hora="1100">Ciencia extrema: El tiburón blanco</evento>
  <evento hora="1130">Serpientes</evento>
 </parrilla>
</programacion>

buscador.xsl ---------------------------------------------------------

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:param name="canal"/>
  <xsl:param name="fecha"/>
  <xsl:param name="busca"/>
  <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"; encoding="ISO-8859-1"
indent="yes" method="xml"/>

  <xsl:template match="/">
  <xsl:apply-templates select="programacion"/>
  </xsl:template>

  <xsl:template match="programacion">
  <xsl:if test="$busca!=''">
    <xsl:if test="($canal!='*')and($fecha!='*')">
    <xsl:variable name="eventos">
      <xsl:value-of
select="count(parrilla[(@canal=$canal)and(@fecha=$fecha)]/evento[contains(.,$busca)])"/>
    </xsl:variable>
    <xsl:if test="$eventos &lt;= 400">
      <xsl:apply-templates
select="parrilla[(@canal=$canal)and(@fecha=$fecha)]/evento[contains(.,$busca)]">
      <xsl:sort select="../@fecha"/>
      <xsl:sort select="@hora"/>
      </xsl:apply-templates>
    </xsl:if>
    </xsl:if>
    <xsl:if test="($canal!='*')and($fecha='*')">
    <xsl:variable name="eventos">
      <xsl:value-of select="count(parrilla[@canal=$canal]/evento[contains(.,$busca)])"/>
    </xsl:variable>
    <xsl:if test="$eventos &lt;= 400">
      <xsl:apply-templates select="parrilla[@canal=$canal]/evento[contains(.,$busca)]">
      <xsl:sort select="../@fecha"/>
      <xsl:sort select="@hora"/>
      </xsl:apply-templates>
    </xsl:if>
    </xsl:if>
    <xsl:if test="($canal='*')and($fecha!='*')">
    <xsl:variable name="eventos">
      <xsl:value-of select="count(parrilla[@fecha=$fecha]/evento[contains(.,$busca)])"/>
    </xsl:variable>
    <xsl:if test="$eventos &lt;= 400">
      <xsl:apply-templates select="parrilla[@fecha=$fecha]/evento[contains(.,$busca)]">
      <xsl:sort select="../@fecha"/>
      <xsl:sort select="@hora"/>
      </xsl:apply-templates>
    </xsl:if>
    </xsl:if>
    <xsl:if test="($canal='*')and($fecha='*')">
    <xsl:variable name="eventos">
      <xsl:value-of select="count(parrilla[@fecha=$fecha]/evento[contains(.,$busca)])"/>
    </xsl:variable>
    <xsl:if test="$eventos &lt;= 400">
      <xsl:apply-templates select="parrilla/evento[contains(.,$busca)]">
      <xsl:sort select="../@fecha"/>
      <xsl:sort select="@hora"/>
      </xsl:apply-templates>
    </xsl:if>
    </xsl:if>
  </xsl:if>
  </xsl:template>

  <xsl:template match="evento">
  <div class="evento">
    <xsl:value-of select="../../canal[@id=current()/../@canal]"/>
    <xsl:value-of select="../@fecha"/>
    <xsl:value-of select="@hora"/>
    <xsl:value-of select="."/>
  </div>
  </xsl:template>

</xsl:transform>


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread