I have an xml document with multiple page references inside <ref> elements. I
have to add 2 to each page reference that follows the text TG:
<ref><b>TG: </b>pp. 19, 20, 21, 29, 32, 40, 43, 44, 46, 56, 57, 58, 60, 61, 66,
67–68</ref>
As you can see above, the list can contain one or more series, as in 67-68
(with an en-dash).
Here is my series of templates, one that captures the page numbers using
tokenize(); the other that adds 2 to each number and that reassembles the list
of references. The templates work. However, I am wondering if there is a more
direct way to accomplish the same thing. Perhaps using analyze string or some
other approach.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"></xsl:output>
<!-- identity template-->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!--Capture the page numbers as attributes to page element-->
<!-- and save TGpages varible -->
<xsl:template match="ref[b/text()='TG: ']">
<xsl:variable name="TGpages">
<pages>
<xsl:for-each select="tokenize(., '\. ')">
<xsl:if test="position()=1">
<prefix><xsl:value-of select="."/></prefix>
</xsl:if>
<xsl:if test="position()=2">
<xsl:for-each select="tokenize(.,', ')">
<xsl:choose>
<xsl:when test="matches(.,'–')">
<page><xsl:for-each select="tokenize(.,'–')">
<xsl:if test="position()=1">
<xsl:attribute name="firstpage" select="."/>
</xsl:if>
<xsl:if test="position()=2">
<xsl:attribute name="lastpage" select="."/>
</xsl:if>
</xsl:for-each></page>
</xsl:when>
<xsl:otherwise>
<page>
<xsl:attribute name="page">
<xsl:value-of select="."/>
</xsl:attribute>
</page>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:for-each></pages></xsl:variable>
<xsl:apply-templates select="$TGpages"/>
</xsl:template>
<!-- Add 2 to each page number and put it all -->
<!-- back together again. -->
<xsl:template match="pages">
<xsl:variable name="numPage" select="count(page)"/>
<ref>
<xsl:choose>
<xsl:when test="$numPage > 1">
<b>TG: </b><xsl:text>pp. </xsl:text>
</xsl:when>
<xsl:when test="$numPage = 1 and .[@firstpage|@lastpage]">
<b>TG: </b> <xsl:text>pp. </xsl:text>
</xsl:when>
<xsl:otherwise>
<b>TG: </b><xsl:text>p. </xsl:text>
</xsl:otherwise>
</xsl:choose>
<!-- put comma back in -->
<xsl:for-each select="page">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
<xsl:apply-templates/>
</xsl:if>
<xsl:if test="position()=1">
<xsl:apply-templates/>
</xsl:if>
<!-- add 2 to each attribute -->
<xsl:for-each select="@firstpage">
<xsl:value-of select=".+2"/><xsl:text>–</xsl:text>
</xsl:for-each>
<xsl:for-each select="@lastpage">
<xsl:value-of select=".+2"/>
</xsl:for-each>
<xsl:for-each select="@page">
<xsl:value-of select=".+2"/>
</xsl:for-each>
</xsl:for-each>
</ref>
</xsl:template>
</xsl:stylesheet>
--~------------------------------------------------------------------
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>
--~--