source and stylesheet below
Problem.
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.
Any suggestions please.
TIA DaveP
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>
</book>
xslt of interest.
<xsl:template match="title" >
<xsl:variable name='this' select='.'/>
<block role="{(_at_)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[(_at_)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[(_at_)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[(_at_)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>
</xsl:template>
<!-- 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>
regards
--
Dave Pawson
XSLT XSL-FO FAQ.
http://www.dpawson.co.uk
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--