a.css

esbudellant estàndards


Generació d'un sumari amb XSLT 1.0 a partir d'un HTML

10/12/07

El problema de fons a l'hora de generar un sumari des d'una jerarquia explícita com la d'un HTML és la dificultat de relacionar una capçalera amb la seva capçalera pare.

El mètode més còmode, curt i ràpid pel processador XSLT és l'anomenat Muenchian Method, que es basa en l'ús de l'element KEY per fer la selecció de nodes relacionats jerarquicament amb el context.

Com que el resultat serà una llista on cada ítem correspondrà al primer nivell (H1) i dins d'aquests, si pertoca, una llista amb els seus elements H2 etc. el TEMPLATE inicial haurà de contenir:


<ul>
   <xsl:apply-templates select="//h1"/>
</ul>

Cal definir un element KEY un per cada nivell de jeraquia (en aquest cas de l'H2 a l'H6). Tots ells amb el mateix nom.

L'expressió XPath de l'atribut "use" ha de seleccionar el primer node de tipus capçalera de nivell superior del context.

Com que posteriorment s'ha de fer una comparació d'igualtat entre nodes, la forma més segura és usant la funció generate-id() ja que aquesta genera un identificador únic per node i evita possibles coincidencies.

Per tant, pels elements H2 cal fer quelcom tipus:


<xsl:key name="next-headings" match="h2"
         use="generate-id( preceding::h1[1] )"/>

pels H3:


<xsl:key name="next-headings" match="h3"
         use="generate-id( preceding::*[self::h1 or
                                       self::h2][1] )"/>

i així fins l'H6:


<xsl:key name="next-headings" match="h6"
         use="generate-id( preceding::*[self::h1 or
                                       self::h2 or
                                       self::h3 or
                                       self::h4 or
                                       self::h5][1] )"/>

Finalment cal declarar el TEMPLATE que seleccioni qualsevol capçalera generant un ítem per cada una d'elles i, en cas de tenir nodes de menor jerarquia depenents d'ell, crear l'element UL pertinent:


<xsl:template match="h1 | h2 | h3 | h4 | h5 | h6">
   <li>
      <xsl:apply-templates />
         <xsl:if test="key( 'next-headings', generate-id() )">
            <ul>
               <xsl:apply-templates select="key( 'next-headings', generate-id() )"/>
            </ul>
         </xsl:if>
   </li>
</xsl:template>

Així doncs, donat un HTML tal que:


<h1>item 1</h1>
<div>
	<h1>item 2</h1>
	<div>
		<h2>item 2.1</h2>
		<p>Lorem ipsum dolor sit amet</p>
	</div>
	<div>
		<div>
			<h2>item 2.2</h2>
			<p>Lorem ipsum dolor sit amet</p>
			<p>Lorem ipsum dolor sit amet</p>
			<p>Lorem ipsum dolor sit amet</p>
			<div>
				<h3>item 2.2.1</h3>
			</div>
		</div>
	</div>
	<h2>item 2.3</h2>
</div>
<h1>item 3</h1>

L'arbre generat mitjançant l'XSLT seria:


<ul>
   <li>
      item 1
   </li>
   <li>
      item 2
      <ul>
         <li>
            item 2.1
         </li>
         <li>
            item 2.2
            <ul>
               <li>
                  item 2.2.1
               </li>
            </ul>
         </li>
         <li>
            item 2.3
         </li>
      </ul>
   </li>
   <li>
      item 3
   </li>
</ul>

Recursos relacionats

Comentaris

Afegir un comentari


© Arnau Siches. a.css està sota Llicència Creative Commons.