Subject: [xsl] Grouping problem. 2.0 From: Dave Pawson <davep@xxxxxxxxxxxxx> Date: Fri, 04 Jul 2008 15:46:34 +0100 |
I want to number the 'blocks' as in 'legal' format 1.1 1.1.1 etc.
Something is wrong with the named template 'number' I'm looking for the set of preceding-siblings between '.' and the preceding-sibling::title with one higher level (@role).
The theory is that recursing on that will enumerate the the 'block' appropriately.
source <book > <title role="1">L1</title>
<title role="2">L1.1</title> <para>This document defines an XML schema for ....</para> <title role="2">L1.2</title> <para>The normative XML Schema for the OpenDoc ....</para> <title role="1">L2</title> <para>This chapter introduces the structure of ....</para> <para>In the OpenDocument format, each structu ....</para>
<title role="2">L2.1</title> <para>A document root element is the primary e ....</para>
<title role="3">L2.1.1</title> <para>The content models of the five root elem ....</para>
<title role="4">L4 test</title> <para>The content models of the five root elem ....</para> <para>The <office:document> root contains a co ....</para>
<title role="4">L4 test 2.1.1.2</title> <para>The content models of the five root elem ....</para> <para>The <office:document> root contains a co ....</para>
<title role="2">L2.1</title> <para>A document root element is the primary e ....</para>
<xsl:template match="title" > <xsl:variable name='this' select='.'/> <block role="{@role}"> <xsl:attribute name='sect'> <xsl:call-template name="number"> <xsl:with-param name='lvl' select='@role'/> </xsl:call-template> </xsl:attribute> <title><xsl:value-of select="."/></title> <xsl:apply-templates select="following-sibling::para[preceding::title[1]=$this]" mode='group'/> </block> </xsl:template>
<xsl:template match="para" mode="group"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:copy-of select="*|text()"/> </xsl:copy> </xsl:template>
<!-- Work out the numbering for $lvl n --> <xsl:template name="number"> <xsl:param name='lvl' as="xs:integer"/> <!-- h1..h6 --> <xsl:param name='n' select='0.0' as='xs:decimal'/> <!-- hdg # -->
<xsl:choose> <!-- Higher levels --> <xsl:when test="$lvl > 1"> <xsl:variable name='higher' select="preceding-sibling::title[@role > $lvl][1]" /> <xsl:if test="not($higher/@role)"> <xsl:message terminate='yes'> Higher is empty Level is <xsl:value-of select="$lvl"/> <xsl:text>, content [ </xsl:text> <xsl:value-of select="."/> </xsl:message> </xsl:if> <xsl:variable name='prev' select="count(preceding-sibling::title[@role = $lvl] [ $higher << .])"/> <xsl:variable name='res' select="dp:dec($lvl, $prev) + $n"/>
<!-- Process higher levels --> <xsl:for-each select="$higher"> <xsl:call-template name="number"> <xsl:with-param name='lvl' select='$lvl - 1'/> <xsl:with-param name="n" select='$res'/> </xsl:call-template> </xsl:for-each> </xsl:when> <!-- Level 1 --> <xsl:when test="$lvl = 1"> <xsl:variable name='prev' select="count(preceding-sibling::title[@role='1'])"/> <xsl:variable name='res' select="dp:dec($lvl, $prev) + $n"/> <xsl:call-template name="number"> <xsl:with-param name='lvl' select='$lvl - 1'/> <xsl:with-param name="n" select='$res'/> </xsl:call-template> </xsl:when> <!-- Terminating Condition --> <xsl:otherwise> <xsl:value-of select="$n"/> </xsl:otherwise> </xsl:choose>
<!-- calculate decimal value from level --> <!-- Inputs: level (from heading level, 1..4) count : # of preceding items at this level @return: decimal, representing a value to be used for this Note. Since levels are 0 based, 1 is added each time. heading. Mappings: lvl count @return 1 0 1.0 2 0 0.1 3 1 0.02 4 2 0.003 5 ? error, fails --> <xsl:function name="dp:dec" as='xs:decimal'> <xsl:param name='lvl' /> <xsl:param name='count' as='xs:integer'/> <xsl:if test='$lvl < 1 or $lvl > 4'> <xsl:message terminate='yes'> Invalid input to dp:dec, <xsl:value-of select='$lvl'/> </xsl:message> </xsl:if> <xsl:variable name='dcount' as ='xs:decimal' select='($count + 1) cast as xs:decimal'/> <xsl:variable name='n'> <xsl:choose> <xsl:when test="$lvl = 4"> <xsl:value-of select="$dcount * 0.001"/> </xsl:when> <xsl:when test="$lvl = 3"> <xsl:value-of select="$dcount * 0.01"/> </xsl:when> <xsl:when test="$lvl = 2"> <xsl:value-of select="$dcount * 0.1"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$dcount * 1.0"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:value-of select="$n"/> </xsl:function>
-- Dave Pawson XSLT XSL-FO FAQ. http://www.dpawson.co.uk
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Is it possible to access , Michael Ludwig | Thread | Re: [xsl] Grouping problem. 2.0, Andrew Welch |
Re: [xsl] Is it possible to access , XemonerdX | Date | Re: [xsl] Grouping problem. 2.0, Andrew Welch |
Month |