Question

I've the below XML.

 <?xml version="1.0" encoding="UTF-8"?>
    <chapter>
        <toc>
            <toc-part>
                <toc-div>
                    <toc-item>
                        <toc-title>8.1 Introduction</toc-title>
                        <toc-pg>749</toc-pg>
                        <toc-subitem level="1">
                            <toc-title>Importance and vitality of contracts</toc-title>
                            <toc-pg>750</toc-pg>
                        </toc-subitem>
                    </toc-item>
                    <toc-item>
                        <toc-title>8.2 The Electronic Transactions Act</toc-title>
                        <toc-pg>751</toc-pg>
                        <toc-subitem level="1">
                            <toc-title>Introduction</toc-title>
                            <toc-pg>751</toc-pg>
                        </toc-subitem>
                    </toc-item>
                </toc-div>
            </toc-part>
        </toc>

        <page num="747"/>
        <section level="sect1">
            <title><content-style font-style="bold">8.1 INTRODUCTION</content-style></title>
            <para num="8.1.1">One definition of information technology (&#8216;IT&#8217;) </para>
            <para num="8.1.2">Without doubt,</para>
            <section level="sect2">
                <title><content-style font-style="bold">Importance and vitality of contracts</content-style></title>
                <para num="8.1.7">Contracts are of fundamental importance to IT transactions. As the Court of Appeal noted in </para>
                <para num="8.1.8">The case is also</para>
            </section>
        </section>
        <section level="sect1">
            <title><content-style font-style="bold">8.2 THE ELECTRONIC TRANSACTIONS ACT</content-style></title>
            <section level="sect2">
                <title><content-style font-style="bold">Introduction</content-style></title>
                <para num="8.2.1">TheThere are key provisions on electronic contracts, electronic and digital signatures and electronic records.</para>
            </section>
    <section level="sect2">
<title><content-style font-style="bold">Purpose and construction</content-style></title>
<para num="8.2.5">The ETA has an uncommon feature among the body of</para>
</section>
        </section>
    </chapter>

and the below XSLT

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:ntw="Number2Word.uri"
    exclude-result-prefixes="ntw">
    <xsl:output method="html"/>
    <xsl:strip-space elements="*"/>


    <xsl:variable name="ThisDocument" select="document('')"/>


    <xsl:template match="/">
        <xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE html>]]></xsl:text>

        <html>
            <body>
                <xsl:apply-templates select="chapter" />
            </body>

        </html>
    </xsl:template>
    <xsl:template match="chapter">
        <xsl:apply-templates />
    </xsl:template>
    <xsl:template name="toc-item" match="chapter/toc/toc-part/toc-div/toc-item">
        <xsl:variable name="tocpg">
            <xsl:value-of select="concat('P',current()/toc-pg/text())"/>
        </xsl:variable>
        <xsl:variable name="tocpgtag" select="translate($tocpg,'.', '-')"/>
        <xsl:variable name="chapternumber">
            <!-- Get num attribute of parent node -->
            <xsl:value-of select="ancestor::chapter[1]/@num"/>
        </xsl:variable>
        <xsl:variable name="strl">
            <xsl:value-of select="string-length(substring-after(@num,'.'))"/>
        </xsl:variable>

        <xsl:variable name="Brac">
            <xsl:choose>
                <xsl:when test="contains(substring-after(@num,'.'),'.')">
                    <xsl:value-of select="3"/>
                </xsl:when>
                <xsl:when test="contains(@num,'(')">
                    <xsl:value-of select="2"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="1"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="NewL">
            <xsl:value-of select="string-length(substring-before(current()/toc-pg,'.'))"/>
        </xsl:variable>
        <xsl:variable name="newNum">
            <xsl:choose>
                <xsl:when test="$NewL=1">
                    <xsl:value-of select="concat('0',substring-before(current()/toc-pg/text(),'.'))"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="substring-before(current()/toc-pg/text(),'.')"/>

                </xsl:otherwise>
            </xsl:choose>

        </xsl:variable>
        <xsl:variable name="d">
            <xsl:value-of select="concat('toc-item-',$ThisDocument//ntw:nums[@num=$Brac]/@word,'-level')"/>
        </xsl:variable>
        <xsl:variable name="new">
            <xsl:value-of select="concat('er:#LRSC_CH_',$newNum,'/',$tocpgtag)"/>
        </xsl:variable>
        <table class="{$d}">
            <tbody>
                <tr>
                    <td class="toc-item-num">
                        <xsl:value-of select="current()/@num"/>
                    </td>
                    <td class="toc-title">
                        <xsl:value-of select="current()/toc-title"/>
                    </td>
                    <xsl:variable name="toc-title" select="upper-case(current()/toc-title/text())" />

                    <td class="toc-pg">
                        <xsl:variable name="refe">
                            <xsl:choose>
                                <xsl:when test="//section[title/*[upper-case(text()) = $toc-title]]/section[1]/para[1]/@num">
                                    <xsl:value-of select="//section[title/*[upper-case(text()) = $toc-title]]/section[1]/para[1]/@num[1]"/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="//section[title/*[upper-case(text()) = $toc-title]]/para[1]/@num[1]"/>            
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:variable>
                        <xsl:variable name="full">
                            <xsl:value-of select="$refe"/>
                        </xsl:variable>
                        <xsl:variable name="pre">
                            <xsl:value-of select="substring-before($refe,'.')"/>              
                        </xsl:variable>
                        <xsl:variable name="post">
                            <xsl:value-of select="substring-after($refe,'.')"/></xsl:variable>
                        <xsl:variable name="siz">
                            <xsl:choose>
                                <xsl:when test="$pre>'1'">
                                    <xsl:value-of select="concat('LRSC_CH_',$pre,'/P',translate($full,'.','-'))"></xsl:value-of>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="concat('LRSC_CH_0',$pre,'/P',translate($full,'.','-'))"></xsl:value-of>
                                </xsl:otherwise>                  
                            </xsl:choose>
                        </xsl:variable>
                        <a href="{$siz}">
                            <xsl:value-of select="./toc-pg"/>
                        </a>
                    </td>
                </tr>
            </tbody>
        </table>
        <xsl:if test="./toc-subitem">
            <xsl:for-each select="./toc-subitem">
                <xsl:apply-templates select="."/>       
            </xsl:for-each>
        </xsl:if>
        <!--</table>-->
    </xsl:template>

    <xsl:template match="toc-subitem">
        <xsl:variable name="tocpg">
            <xsl:value-of select="concat('P',current()/toc-pg/text())"/>
        </xsl:variable>
        <xsl:variable name="tocpgtag" select="translate($tocpg,'.', '-')"/>
        <xsl:variable name="chapternumber">
            <!-- Get num attribute of parent node -->
            <xsl:value-of select="ancestor::chapter[1]/@num"/>
        </xsl:variable>
        <xsl:variable name="strl">
            <xsl:value-of select="string-length(substring-after(@num,'.'))"/>
        </xsl:variable>

        <xsl:variable name="Brac">
            <xsl:choose>
                <xsl:when test="contains(substring-after(@num,'.'),'.')">
                    <xsl:value-of select="3"/>
                </xsl:when>
                <xsl:when test="contains(@num,'(')">
                    <xsl:value-of select="2"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="1"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="NewL">
            <xsl:value-of select="string-length(substring-before(current()/toc-pg,'.'))"/>
        </xsl:variable>
        <xsl:variable name="newNum">
            <xsl:choose>
                <xsl:when test="$NewL=1">
                    <xsl:value-of select="concat('0',substring-before(current()/toc-pg/text(),'.'))"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="substring-before(current()/toc-pg/text(),'.')"/>

                </xsl:otherwise>
            </xsl:choose>

        </xsl:variable>
        <xsl:variable name="d">
            <xsl:value-of select="concat('toc-item-',$ThisDocument//ntw:nums[@num='2']/@word,'-level')"/>
        </xsl:variable>
        <xsl:variable name="new">
            <xsl:value-of select="concat('er:#LRSC_CH_',$newNum,'/',$tocpgtag)"/>
        </xsl:variable>
        <table class="{$d}">
            <tbody>
                <tr>
                    <td class="toc-item-num">
                        <xsl:value-of select="current()/@num"/>
                    </td>
                    <td class="toc-title">
                        <xsl:value-of select="current()/toc-title"/>
                    </td>
                    <xsl:variable name="toc-title" select="current()/toc-title/*" />
                    <!--
                    <td class="toc-pg">
                    <xsl:variable name="refe">
                    <xsl:choose>
               <xsl:when test="//section[title/*[upper-case(text()) = $toc-title]]/section[1]/para[1]/@num[1]">
                    <xsl:value-of select="//section[title/*[upper-case(text()) = $toc-title]]/section[1]/para[1]/@num[1]"/>
                    </xsl:when>
                    <xsl:otherwise>
        <xsl:value-of select="//section[title/*[upper-case(text()) = $toc-title]]/para[1]/@num[1]"/>            
                    </xsl:otherwise>
                    </xsl:choose>
                      </xsl:variable>
                      <xsl:variable name="full">
                          <xsl:value-of select="$refe"/>
                      </xsl:variable>
                      <xsl:variable name="pre">
        <xsl:value-of select="substring-before($refe,'.')"/>              
                      </xsl:variable>
                      <xsl:variable name="post">
                      <xsl:value-of select="substring-after($refe,'.')"/></xsl:variable>
                      <xsl:variable name="siz">
                          <xsl:choose>
        <xsl:when test="$pre>'1'">
        <xsl:value-of select="concat('LRSC_CH_',$pre,'/P',translate($full,'.','-'))"></xsl:value-of>
        </xsl:when>
        <xsl:otherwise>
        <xsl:value-of select="concat('LRSC_CH_0',$pre,'/P',translate($full,'.','-'))"></xsl:value-of>
        </xsl:otherwise>                  
                          </xsl:choose>
                      </xsl:variable>
                      <a href="{$siz}">
                          <xsl:value-of select="./toc-pg"/>
                      </a>
                    </td>
        -->


                    <td class="toc-pg">
                        <xsl:variable name="refe">
                            <xsl:choose>
                                <xsl:when test="//section[title/node()/text() = $toc-title]/para[1]/@num[1]">
                                    <xsl:value-of select="//section[title/node()/text() = $toc-title]/para[1]/@num[1]"/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="//section[title/node()/text() = $toc-title]/section[1]/para[1]/@num"/>            
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:variable>
                        <xsl:variable name="full">
                            <xsl:value-of select="$refe"/>
                        </xsl:variable>
                        <xsl:variable name="pre">
                            <xsl:value-of select="substring-before($refe,'.')"/>              
                        </xsl:variable>
                        <xsl:variable name="post">
                            <xsl:value-of select="substring-after($refe,'.')"/></xsl:variable>
                        <xsl:variable name="siz">
                            <xsl:choose>
                                <xsl:when test="$pre>'1'">
                                    <xsl:value-of select="concat('LRSC_CH_',$pre,'/P',translate($full,'.','-'))"></xsl:value-of>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="concat('LRSC_CH_0',$pre,'/P',translate($full,'.','-'))"></xsl:value-of>
                                </xsl:otherwise>                  
                            </xsl:choose>
                        </xsl:variable>
                        <a href="{$siz}">
                            <xsl:value-of select="./toc-pg"/>
                        </a>
                    </td>

                </tr>
            </tbody>
        </table>
        <xsl:if test="./toc-subitem">
            <xsl:apply-templates/>        
        </xsl:if>
        <!--</table>-->


    </xsl:template>
  <ntw:nums num="1" word="first"/>
 <ntw:nums num="2" word="second"/>
 <ntw:nums num="3" word="third"/>
 <ntw:nums num="4" word="forth"/>
 <ntw:nums num="5" word="fifth"/>
 <ntw:nums num="6" word="sixth"/>
 <ntw:nums num="7" word="seventh"/>
 <ntw:nums num="8" word="eighth"/>
 <ntw:nums num="9" word="nighth"/>
 <ntw:nums num="10" word="tenth"/>
</xsl:stylesheet>

here what i'm trying to achieve is, first the toc-title is caught and then it goes through the XML document and search and once the toc-title is found i need to get the para num following it. here in my XSLT, it is working fine for toc-item but when doing with toc-subitem, it is pulling a wrong value, and below is a part of my output that i get.

<table class="toc-item-first-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">8.1 Introduction</td>
            <td class="toc-pg">
                <a href="LRSC_CH_8/P8-1-7">749</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-second-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">Importance and vitality of contracts</td>
            <td class="toc-pg">
                <a href="LRSC_CH_0/P">750</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-first-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">8.2 The Electronic Transactions Act</td>
            <td class="toc-pg">
                <a href="LRSC_CH_8/P8-2-1">751</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-second-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">Introduction</td>
            <td class="toc-pg">
                <a href="LRSC_CH_0/P">751</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-second-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">Purpose and construction</td>
            <td class="toc-pg">
                <a href="LRSC_CH_0/P">752</a>
            </td>
        </tr>
    </tbody>
</table>  

The expected output is as below.

<table class="toc-item-first-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">8.1 Introduction</td>
            <td class="toc-pg">
                <a href="LRSC_CH_8/P8-1-7">749</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-second-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">Importance and vitality of contracts</td>
            <td class="toc-pg">
                <a href="LRSC_CH_8/P8-1-7">750</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-first-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">8.2 The Electronic Transactions Act</td>
            <td class="toc-pg">
                <a href="LRSC_CH_8/P8-2-1">751</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-second-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">Introduction</td>
            <td class="toc-pg">
                <a href="LRSC_CH_8/P8-2-1">751</a>
            </td>
        </tr>
    </tbody>
</table>
<table class="toc-item-second-level">
    <tbody>
        <tr>
            <td class="toc-item-num"></td>
            <td class="toc-title">Purpose and construction</td>
            <td class="toc-pg">
                <a href="LRSC_CH_9/P8-2-5">752</a>
            </td>
        </tr>
    </tbody>
</table> 

in toc-subitem, i'm getting the values as <a href="LRSC_CH_0/P">, please let me know where am i going wrong.

Thanks

Was it helpful?

Solution

I added the following block which was missing from your stylesheet (your output is not the same without it):

<ntw:words>
    <ntw:nums num="1" word="first" />
    <ntw:nums num="2" word="second" />
</ntw:words>

I noticed that your code has a lot of code duplication, which is a common source of errors. There are also many unnecessary variables, which add to the complexity. I checked the differences between the item and subitem templates, and noticed that the one that is working tests a string using the upper-case() function, and the other doesn't (it's also slightly different, although t seems to refer to the same elements). So I replaced the $toc-title and the $refe variable definitions from the template which is not working, pasting in its place the exact same code you are using in the template which is working, and the values were copied correctly.

So to fix your problem copy the definitions of these two variables from the toc-item template:

<xsl:variable name="toc-title" select="current()/toc-title/*" />
<xsl:variable name="refe">...</xsl:variable>

and paste them over the definitions of those variables in the toc-subitem template, which don't select anything.

I suggest you spend some time refactoring your stylesheet. You will better understand how it works, it will become much simpler, less error-prone, and will have probably 1/4 of its original size or less. Start by removing duplication and unnecessary variables.

UPDATE

These are the only changes I made in the XSLT file you posted to make it work (copied the $toc-title and $refe definitions from the toc-item template):

<xsl:stylesheet ...> ...
   <xsl:template match="toc-subitem">
     ...
     <xsl:variable name="toc-title" select="upper-case(current()/toc-title/text())" />
     ...
     <xsl:variable name="refe">
       <xsl:choose>
        <xsl:when test="//section[title/*[upper-case(text()) = $toc-title]]/section[1]/para[1]/@num">
         <xsl:value-of select="//section[title/*[upper-case(text()) = $toc-title]]/section[1]/para[1]/@num[1]"/>
        </xsl:when>
        <xsl:otherwise>
         <xsl:value-of select="//section[title/*[upper-case(text()) = $toc-title]]/para[1]/@num[1]"/>   
        </xsl:otherwise>
       </xsl:choose>
     </xsl:variable>
    ...
  ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top