Re: [xsl] Enabling extension to counting of instances

Subject: Re: [xsl] Enabling extension to counting of instances
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 08 Jan 2010 16:21:35 -0500
At 2010-01-08 09:08 -0600, Eliot Kimber wrote:
The plugin can't simply override the numbering logic because that would
break other plugins deployed to same Toolkit instance. Rather, plugins need
to be able to contribute to the numbering logic so that all chapters are
counted correctly.

My design challenge then is to determine what is the best way to enable this
sort of unilateral contribution to things like numbering logic. In
particular, typical code using <xsl:number/> with @count and @from won't
work because there's no obvious way to extend the specification of what to
count and what to count from.

The only directly-provided XSLT extension mechanism I can think of is to use
modes where elements contribute nodes to a sequence that is then used for
either counting or doing a boolean check.

For example, to count chapter references you would have a mode
"isChapterRef" and then use it like so:

<xsl:variable name="chapterRefs"
  as="element()*"
>
  <xsl:apply-templates mode="isChapterRef"
   select="$map//*[contains(@class, ' map/topicref ')]"/>
</xsl:variable/>

Where a typical isChapterRef template would be:

<xsl:template mode="isChapterRef"
  match="*[contains(@class, ' pubmap-d/chapterref ')]"
>
 <xsl:sequence select="."/>
</xsl:template>

So that the resulting value of $chapterRefs would be a list of elements that
have declared themselves to be chapter references.

The $chapterRefs list can then be used for counting, boolean checks, etc.

My question: is there a more efficient way to provide this sort of
extensible arbitrary-type-to-semantic-type mapping?

For numbering in particular, could you perhaps create a temporary tree composed of vocabulary constructs of your choice that have a particular counting semantic? Then the way a DITA deployment effects counting is by creating the temporary tree however they want and then passing that tree to your library for counting purposes.


But you might loose some context issues ... you might need to copy id= values into the temporary tree to associate counted values.

Where I thought you were going with this thread was the dynamic extensibility of a stylesheet library for unknown future functionality thereby needing ultimate flexibility. And just as you intuited, I ended up using modes.

This was a requirement for an intelligence documents project where different commands needed the power to augment a standard library in ways we wouldn't know before publishing the library:

http://www.CraneSoftwrights.com/links/ipepaper.htm

In that project I employed a technique I'd used before elsewhere for a shared library that needed that flexibility. A number of hooks are built in to the processing of *every* construct, because we had no idea *which* construct users might want to tweak.

To summarize, consider the following library construct to process <para> into an <fo:block>:

    <xsl:template match="para">
      <xsl:apply-templates mode="do-construct" select="."/>
    </xsl:template>
    <xsl:template match="para" mode="do-construct">
       <fo:block xsl:use-attribute-sets="normal-stuff">
         <xsl:apply-templates mode="do-attributes" select="."/>
         <xsl:apply-templates mode="do-content" select="."/>
       </fo:block>
    </xsl:template>
    <xsl:template match="para" mode="do-attributes">
      <xsl:apply-templates select="@*"/>
    </xsl:template>
    <xsl:template match="para" mode="do-content">
      <xsl:apply-templates/>
    </xsl:template>

It was very labourious work on my part to write out the above (actually we ended up only doing a subset of the above) for every construct, but it meant the library was customizable for each and every item in the vocabulary because of all the hooks.

Using an importing stylesheet, user groups could turn off attributes, substitute content, prefix or suffix attributes and/or content, do nothing and use solely the library facilities, or anything in-between. The paper shows the import tree and the number of modules being used to format the intelligence documents.

Back to numbering, imagine modifying the above with the following assuming that all paragraphs were numbered and you wanted to give flexibility in numbering:

    <xsl:template match="para">
      <xsl:apply-templates mode="do-construct" select="."/>
    </xsl:template>
    <xsl:template match="para" mode="do-construct">
       <fo:block xsl:use-attribute-sets="normal-stuff">
         <xsl:apply-templates mode="do-attributes" select="."/>
         <xsl:apply-templates mode="do-content" select="."/>
       </fo:block>
    </xsl:template>
    <xsl:template match="para" mode="do-content">
      <xsl:apply-templates mode="do-number" select="."/>
      <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="para" mode="do-number">
       <xsl:number/>: <xsl:text/>
    </xsl:template>

... then someone could accept the existing way of doing numbering, prefix or suffix it, or simply replace it with their own logic by intercepting the element in the "do-number" mode.

Back then I was using only XSLT 1.0 ... tunnel parameters in XSLT 2.0 might also be a conduit down which you could pass information that could be intercepted by a user's onion-skin stylesheet.

I hope this helps.

. . . . . . . . . . . . Ken

--
UBL and Code List training:      Copenhagen, Denmark 2010-02-08/10
XSLT/XQuery/XPath training after http://XMLPrague.cz 2010-03-15/19
XSLT/XQuery/XPath training:   San Carlos, California 2010-04-26/30
Vote for your XML training:   http://www.CraneSoftwrights.com/s/i/
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread