xsl-list
[Top] [All Lists]

[xsl] is there a more elegant way to change page references?

2012-05-28 10:42:30
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&#8211;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(.,'&#8211;')">
                            <page><xsl:for-each select="tokenize(.,'&#8211;')">
                                <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>&#8211;</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>
--~--


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