a.css

esbudellant estàndards


Numeració automàtica mitjançant XSLT

13/06/07

Un dels principals problemes que apareix a l'escriure un document amb les seccions numerades és el manteniment d'aquesta numeració al llarg del temps.

Una possible solució és mitjançant l'ús d'XSLT per afegir la numeració de forma automatitzada i senzilla. Aquesta solució serà diferent en funció del tipus de jerarquia que tingui el document original, és a dir:

  • Explícita com l'(X)HTML (H1,H2, etc.)
  • Implícita com el DocBook (encapsulament de SECTION)

En ambdós casos però la solució es basa en l'ús de l'element NUMBER d'XSLT. Aquest element numera un node en funció d'on està i respecte qui s'enumera.

Aproximació des d'un XHTML amb sortida XHTML

Donat un XHTML tal que:


<h1>títol de primer nivell</h1>
<h2>títol de segon nivell</h2>
<p>lorem ipsum...</p>

<h2>títol de segon nivell</h2>
<p>lorem ipsum...</p>

<h3>títol de tercer nivell</h3>
<p>lorem ipsum...</p>

<h3>títol de tercer nivell</h3>
<p>lorem ipsum...</p>
<p>lorem ipsum...</p>

<h1>títol de primer nivell</h1>
<p>lorem ipsum...</p>

<h2>títol de segon nivell</h2>
<p>lorem ipsum...</p>

<h3>títol de tercer nivell</h3>
<p>lorem ipsum...</p>

s'aplicaria un XSLT tal que:


<xsl:template match="html:h1">
   <h1>
      <xsl:number level="any" format="1. "/>
      <xsl:apply-templates/>
   </h1>
</xsl:template>
<xsl:template match="html:h2">
   <h2>
      <xsl:number count="html:h1" level="any" format="1."/>
      <xsl:number from="html:h1" count="html:h2" level="any" format="1. "/>
      <xsl:apply-templates/>
   </h2>
</xsl:template>
<xsl:template match="html:h3">
   <h3>
      <xsl:number count="html:h1" level="any" format="1."/>
      <xsl:number from="html:h1" count="html:h2" level="any" format="1."/>
      <xsl:number from="html:h2" count="html:h3" level="any" format="1. "/>
      <xsl:apply-templates/>
   </h3>
</xsl:template>
...

El document final seria:


<h1>1. títol de primer nivell</h1>
<h2>1.1. títol de segon nivell</h2>
<p>lorem ipsum...</p>

<h2>1.2. títol de segon nivell</h2>
<p>lorem ipsum...</p>

<h3>1.2.1. títol de tercer nivell</h3>
<p>lorem ipsum...</p>

<h3>1.2.2. títol de tercer nivell</h3>
<p>lorem ipsum...</p>
<p>lorem ipsum...</p>

<h1>2. títol de primer nivell</h1>
<p>lorem ipsum...</p>

<h2>2.1. títol de segon nivell</h2>
<p>lorem ipsum...</p>

<h3>2.1.1. títol de tercer nivell</h3>
<p>lorem ipsum...</p>

És a dir, es selecciona cada node de capçalera (H1-6) per separat i se li aplica un NUMBER per cada nivell que es vol mostrar.

Aproximació des d'un DocBook amb sortida XHTML

Donat un DocBook tal que:


<section>
   <title>títol de primer nivell</title>
   <section>
      <title>títol de segon nivell</title>
      <para>Lorem ipsum...</para>
      <section>
         <title>títol de tercer nivell nivell</title>
         <para>Lorem ipsum...</para>
      </section>
   </section>
</section>
<section>
   <title>títol de primer nivell</title>
   <section>
      <title>títol de segon nivell</title>
      <para>Lorem ipsum...</para>
      <section>
         <title>títol de tercer nivell nivell</title>
      </section>
      <section>
         <title>títol de tercer nivell nivell</title>
      </section>
   </section>
</section>

S'aplicaria un XSLT tal que:


<xsl:template match="db:title" name="count.header">
   <xsl:number count="db:section" level="multiple" format="1. "/>
   <xsl:apply-templates/>
</xsl:template>

<xsl:template match="db:title">
   <xsl:variable name="header-depth" select="count(ancestor::db:section)"/>
   <xsl:choose>
      <xsl:when test="parent::db:section">
         <xsl:element name="{concat('h',$header-depth + '1')}">
            <xsl:call-template name="count.header"/>
         </xsl:element>
      </xsl:when>
   </xsl:choose>
</xsl:template>

El document final seria:


<h1>1. títol de primer nivell</h1>
<h2>1.1. títol de segon nivell</h2>
<p>Lorem ipsum...</p>

<h3>1.1.1. títol de tercer nivell nivell</h3>
<p>Lorem ipsum...</p>

<h1>2. títol de primer nivell</h1>
<h2>2.1. títol de segon nivell</h2>
<p>Lorem ipsum...</p>

<h3>2.1.1. títol de tercer nivell nivell</h3>

<h3>2.1.2. títol de tercer nivell nivell</h3>

En aquest cas l'herència es pot calcular automàticament comptant els SECTION relacionats amb el TITLE.

El segon TEMPLATE serveix només per escriure l'element HTML de capçalera que calgui en cada cas.

Comentaris

Afegir un comentari


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