[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Re: transform html h1 with a div


Subject: [xsl] Re: transform html h1 with a div
From: Giuseppe Briotti <g.briotti@xxxxxxxxx>
Date: Wed, 31 Oct 2012 21:58:27 +0000 (UTC)

Thanks David, thanks Gerrit. At the moment, your solutions both works on my test
cases (I need only to change

    <xsl:template match="body" name="x">      <-------------- match body element
        <xsl:param name="level" select="1"/>  <-------------- default level=1
        <xsl:param name="content" select="*"/>

in David solution).

I've correct my xslt and it seems to work too, but it is not so nice and compact
as yours (I've a lot to learn :-) ):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xhtml" indent="yes"/>

    <!-- IT: identitC   -->
    <!-- EN: identity -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- IT: body del documento html -->
    <!-- EN: body of html document -->
    <xsl:template match="body">
        <!-- IT: selezione primi gruppi e innesco della ricorsione -->
        <!-- EN: first groups selection and starting of recursion -->
        <body>
            <xsl:for-each-group select="*"
                group-starting-with="*[local-name()='h1'
                or (local-name()='h2' and count(preceding-sibling::h1)=0)
                or (local-name()='h3' and count(preceding-sibling::h1
 | preceding-sibling::h2 )=0)
                or (local-name()='h4' and count(preceding-sibling::h1
 | preceding-sibling::h2  | preceding-sibling::h3 )=0)
                or (local-name()='h5' and count(preceding-sibling::h1 
 | preceding-sibling::h2  | preceding-sibling::h3 | preceding-sibling::h4 )=0)
                or (local-name()='h6' and count(preceding-sibling::h1 |
preceding-sibling::h2  | preceding-sibling::h3 | preceding-sibling::h4 |
preceding-sibling::h5 )=0)
                ]">
                <xsl:call-template name="gruppo"/>
            </xsl:for-each-group>
        </body>
    </xsl:template>

    <!-- IT: template che processa il singolo gruppo, ricorsivo -->
    <!-- EN: template processing a single group, recursive -->
    <xsl:template name="gruppo">
        <xsl:variable name="inizio" select="."/>
        <xsl:choose>
            <!-- IT: l'elemento iniziale C( un header, quindi 
devo creare il div -->
            <!-- EN: the first element in group is a header, 
thus a div must be inserted -->
            <xsl:when
                test="local-name()='h1' or local-name()='h2' or
local-name()='h3' or local-name()='h4' or 
local-name()='h5' or local-name()='h6'">
                <xsl:element name="div">

<!-- IT: attributo class del div pari al 
nome dell'header -->
<!-- EN: div class attribute, value equal to header
local-name -->
                    <xsl:attribute name="class">
                        <xsl:value-of select="local-name()"/>
                    </xsl:attribute>

<!-- IT: ricopiamo il tag dell'header -->
<!-- EN: recreate the header -->
                    <xsl:element name="{local-name()}">
                        <xsl:apply-templates select="@*|node()"/>
                    </xsl:element>

<!-- IT: processiamo il gruppo corrente, a meno del primo
elemento che abbiamo appena inserito -->
<!-- EN: current group processing, with first element
exclusion  -->
                    <xsl:for-each-group select="current-group() except ."
                        group-starting-with="*[ (local-name()='h1'
or (local-name()='h2' and
      count(preceding-sibling::h1[.>>$inizio])=0)
or (local-name()='h3' and
      count((preceding-sibling::h1[.>>$inizio]) | 
            (preceding-sibling::h2[.>>$inizio]) )=0)
or (local-name()='h4' and
      count((preceding-sibling::h1[.>>$inizio]) | 
            (preceding-sibling::h2[.>>$inizio]) | 
            (preceding-sibling::h3[.>>$inizio]) )=0)
or (local-name()='h5' and
      count((preceding-sibling::h1[.>>$inizio]) | 
            (preceding-sibling::h2[.>>$inizio]) | 
            (preceding-sibling::h3[.>>$inizio]) | 
            (preceding-sibling::h4[.>>$inizio]) )=0)
or (local-name()='h6' and
      count((preceding-sibling::h1[.>>$inizio]) | 
            (preceding-sibling::h2[.>>$inizio]) | 
            (preceding-sibling::h3[.>>$inizio]) | 
            (preceding-sibling::h4[.>>$inizio]) |
            (preceding-sibling::h5[.>>$inizio]) )=0) )
                        ]">
                        <xsl:call-template name="gruppo"/>
                    </xsl:for-each-group>
                </xsl:element>
            </xsl:when>
<!-- IT: il gruppo corrente non inizia con un header, quindi non va
inserito un div -->
<!-- EN: the current group first element is not a header, thus no
div is required -->
            <xsl:otherwise>
                <xsl:choose>
<!-- IT: se non ci sono header, ricopiamo gli elementi del gruppo -->
<!-- EN: if not header in the group, copy the current-group elements -->
                    <xsl:when
                        test="count(current-group()[self::h1 | self::h2 |
self::h3 | self::h4 | self::h5 | self::h6])=0">
                        <xsl:for-each select="current-group()">
                            <xsl:apply-templates select="current()"/>
                        </xsl:for-each>
                    </xsl:when>

<!-- IT: se ci sono header, allora occorre continuare con la ricorsione -->
<!-- EN: if there are headers, thus the recursion must proceed -->
                    <xsl:otherwise>

<!-- IT: ricopiamo il tag del primo elemento -->
<!-- EN: the first element must be copied -->
                        <xsl:element name="{local-name()}">
                            <xsl:apply-templates select="@*|node()"/>
                        </xsl:element>

<!-- IT: processiamo il gruppo corrente, a meno del
primo elemento che abbiamo appena inserito -->
<!-- EN: current group processing, with first element exclusion  -->
                        <xsl:for-each-group select="current-group() except ."
                            group-starting-with="*[ 
(local-name()='h1' or (local-name()='h2' and
count(preceding-sibling::h1[.>>$inizio])=0)
or (local-name()='h3' and
count((preceding-sibling::h1[.>>$inizio]) | 
      (preceding-sibling::h2[.>>$inizio]) )=0)
or (local-name()='h4' and
count((preceding-sibling::h1[.>>$inizio]) | 
      (preceding-sibling::h2[.>>$inizio]) | 
      (preceding-sibling::h3[.>>$inizio]) )=0)
or (local-name()='h5' and
count((preceding-sibling::h1[.>>$inizio]) | 
      (preceding-sibling::h2[.>>$inizio]) | 
      (preceding-sibling::h3[.>>$inizio]) | 
      (preceding-sibling::h4[.>>$inizio]) )=0)
or (local-name()='h6' and
count((preceding-sibling::h1[.>>$inizio]) | 
      (preceding-sibling::h2[.>>$inizio]) | 
      (preceding-sibling::h3[.>>$inizio]) | 
      (preceding-sibling::h4[.>>$inizio]) |
      (preceding-sibling::h5[.>>$inizio]) )=0) )
                             ]">
                            <xsl:call-template name="gruppo"/>
                        </xsl:for-each-group>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <!-- IT: processiamo l'header html per inserire lo stile prima
     di processare il resto  -->
    <!-- EN: processing html header to place some CSS for debug -->
    <xsl:template match="head">
        <head>
            <xsl:message>
                <xsl:text>head</xsl:text>
            </xsl:message>
            <style type="text/css">
                div.h1{
                    border-width:1;
                    border:solid;
                    background-color:#FFFF33;
                    width:95%;
                }
                div.h2{
                    border-width:1;
                    border:solid;
                    background-color:#FF9933;
                    width:95%;
                }
                div.h3{
                    border-width:1;
                    border:solid;
                    background-color:#FF0033;
                    width:95%;
                }
                div.h4{
                    border-width:1;
                    border:solid;
                    background-color:#99FFFF;
                    width:95%;
                }
                div.h5{
                    border-width:1;
                    border:solid;
                    background-color:#9999FF;
                    width:95%;
                }
                div.h6{
                    border-width:1;
                    border:solid;
                    background-color:#9933FF;
                    width:95%;
                }</style>
            <xsl:apply-templates/>
        </head>
    </xsl:template>

</xsl:stylesheet>


Current Thread
Keywords