xsl-list
[Top] [All Lists]

Re: [xsl] Kosher XSLT 3.0 numbering solution?

2016-09-01 09:18:06
I haven't previously used xsl:accumulator but that would appear to be the native solution in 3.0--thanks for the pointer! (If there's an elegant XSLT 2 solution I'd still be interested in hearing.)

David

On Thu, 1 Sep 2016, Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de wrote:

On 01.09.2016 15:51, David Sewell dsewell(_at_)virginia(_dot_)edu wrote:
I have a numbering task that is trivially easy to handle using an XSLT
extension that permits modification of global variables (such as
saxon:assign) but which is harder to accomplish via pure XSLT. I don't
*need* to accomplish this as I have code that works fine, but I'm just
curious about alternate solutions.

I have an XML file representing the contents of a printed book. I need
to add page break indicators that carry the page numeration, e.g. <pb
n="51"/>. Because I'm lazy, I just want to plug in empty  markers and
then run a script to add the numeration.

This would be a straightforward job for xsl:number if all pagination was
sequential. However, parts of the book are commented out, so there may
be a page jump from say page 11 to page 30. In a case like that, I will
insert <pb n="30"/> to provide a hard-coded indication of the number.
That makes use of xsl:number more complicated. The solution via updates
to a global variable is simple, along the lines of

  <xsl:variable name="bodyPageNo" select="0" as="xs:integer"
saxon:assignable="yes"/>
  <xsl:template match="pb">
    <xsl:variable name="pageNumber">
       <saxon:assign name="bodyPageNo" select="
          if (@n) then xs:integer(@n) else $bodyPageNo + 1
          "/>
       <xsl:value-of select="$bodyPageNo"/>
    </xsl:variable>
   [etc.]

If I avoid saxon:assign, I don't see any way around some moderately
messy brute-force calculation in the <pb> template to identify the
closest preceding <pb> element with an @n value (if any), and use that
value plus the number of intervening <pb> elements to assign a
numeration to the current element. Does anything jump out as a more
elegant approach?


I wonder, given XSLT 3.0 as the target, whether the above does not translate directly into an accumulator e.g.

<xsl:accumulator name="bodyPageNo" as="xs:integer" initial-value="0">
<xsl:accumulator-rule match="pb" select="if (@n) then xs:integer(@n) else $value + 1"/>
</xsl:accumulator>

then elsewhere you can use

 accumulator-before('bodyPageNo')

respectively

 accumulator-after('bodyPageNo')



--
David Sewell
Manager of Digital Initiatives
The University of Virginia Press
Email: dsewell(_at_)virginia(_dot_)edu   Tel: +1 434 924 9973
Web: http://www.upress.virginia.edu/rotunda
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>