user3111030
user3111030

Reputation: 79

select the string before ":" or a function like first() in xslt

i wish to select the string before ":" or a function like first() in xslt

my input is

<E T="B">1.1.1-CES: Describe the normal anatomy.</E>

expected output is

<span class="emph_B">
  <span class="emph_Bcol">1.1.1-CES:</span>
  Describe  the normal  anatomy.
</span>

i am having trouble selecting the first string i.e (1.1.1-CES before :)

presently on doing the following:

        <xsl:template match="E">
    <span>
        <xsl:attribute name="class">emph_I</xsl:attribute>
        <xsl:if test="contains(.,':')">
        <xsl:variable name="token" select="tokenize(.,': ')[last()]"/>
        <xsl:value-of select="$token"/>
        <xsl:variable name="seprate"  
        select="translate(current(),$token,'')"/>    
        <xsl:value-of select="$seprate"/>
        </xsl:if>
        <xsl:apply-templates />
        </span>
        </xsl:template>

i get the output as

           <div class="P"><img class="rarr" src="images/FFU1.gif"></img><span class="emph_I">Describe  the
                 normal c anatomy.111-CES:1.1.1-CES: Describe  the
                 normal anatomy.</span></div>

is there a function like first() or before() like last() in xslt?

code:

<xsl:template match="/">
    <xsl:apply-templates select="//CHAPTER" />
</xsl:template>

<xsl:template match="CHAPTER">
    <xsl:result-document href="{$pDest}chapter{position()}.xhtml">
        <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE HTML></xsl:text>
        <html>
            <head>
                <title>
                    <xsl:value-of select="CHSO/THD/HD" />
                </title>
                <link rel="stylesheet" type="text/css" href="styles/stylesheet.css" />
            </head>
            <body>
                <div>
                    <xsl:attribute name="class">CHAPTER</xsl:attribute>
                    <div>
                        <xsl:attribute name="class">CHSO</xsl:attribute>
                        <div>
                            <xsl:attribute name="class">THD box-style</xsl:attribute>
                            <div>
                                <xsl:attribute name="class">HNUM</xsl:attribute>
                                <xsl:attribute name="style">text-align:center;color:white;</xsl:attribute>
                                <xsl:value-of select="CHSO/THD/HNUM" />
                            </div>
                            <div>
                                <xsl:attribute name="class">HD</xsl:attribute>
                                <xsl:attribute name="style">text-align:center;color:white;</xsl:attribute>
                                <xsl:value-of select="CHSO/THD/HD" />
                            </div>
                        </div>
                    </div>
                    <xsl:apply-templates />
                </div>
            </body>
        </html>
    </xsl:result-document>
</xsl:template>

<xsl:template match="TBD">
    <div>
        <xsl:attribute name="class">TBD</xsl:attribute>
        <xsl:apply-templates />
    </div>
</xsl:template>

<xsl:template match="TLV1">
    <div>
        <xsl:attribute name="class">TLV1</xsl:attribute>
        <xsl:variable name="chapVal" select="tokenize(../../@CHAN,'-')[last()]" />
        <xsl:variable name="myId"
            select="translate($chapVal,translate($chapVal, '1234567890', ''),'')" />
        <xsl:variable name="tlvId" select="translate(./@ID, '.', '-')" />
        <h2>
            <xsl:attribute name="class">HD</xsl:attribute>
            <xsl:attribute name="id">ch<xsl:value-of
                select="$myId" />-<xsl:value-of select="$tlvId" />
            </xsl:attribute>
            <xsl:attribute name="style">margin-bottom:0.5em;</xsl:attribute>
            <xsl:value-of select="HD" />
        </h2>
        <xsl:apply-templates />
    </div>
</xsl:template>

<xsl:template match="P">
    <div>
        <xsl:attribute name="class">P</xsl:attribute>
        <xsl:apply-templates />
    </div>
</xsl:template>

<xsl:template match="FILE">
    <img>
        <xsl:attribute name="class">rarr</xsl:attribute>
        <xsl:attribute name="src">images/<xsl:value-of
            select="@NAME" />
        </xsl:attribute>
    </img>
</xsl:template>

<xsl:template match="E">
    <span>
        <xsl:attribute name="class">emph_I</xsl:attribute>
        <xsl:if test="contains(.,':')">
        <xsl:variable name="token" select="tokenize(.,': ')[last()]"/>
        <xsl:value-of select="$token"/>
            <xsl:variable name="seprate" select="translate(current(),$token,'')"/>
            <xsl:value-of select="$seprate"/>
        </xsl:if>
        <xsl:apply-templates />
    </span>
</xsl:template>

<xsl:template match="LK">
    <a>
        <xsl:attribute name="class">LK</xsl:attribute>
        <xsl:variable name="chapVal"
            select="tokenize(../../../../@CHAN,'-')[last()]" />
        <xsl:variable name="myId"
            select="translate($chapVal,translate($chapVal, '1234567890', ''),'')" />
        <xsl:attribute name="href">chapter<xsl:value-of
            select="$myId" />.xhtml#<xsl:value-of select="@IDREF" />
        </xsl:attribute>
        <xsl:apply-templates />
    </a>
</xsl:template>

<xsl:template match="SIDEBAR/TLV1">
    <div>
        <xsl:attribute name="class">SIDEBAR <xsl:value-of
            select="@CLASSF" /></xsl:attribute>
        <div>
            <xsl:attribute name="class">TLV1</xsl:attribute>
            <div>
                <xsl:attribute name="class">HD bg-col</xsl:attribute>
                <span>
                    <xsl:attribute name="class">sb-head</xsl:attribute>
                    <span>
                        <xsl:attribute name="class">col-auto</xsl:attribute>
                        <xsl:value-of select="HD"></xsl:value-of>
                    </span>
                </span>
            </div>
            <xsl:if test="P">
                <div>
                    <xsl:attribute name="class">sb-pad</xsl:attribute>
                    <xsl:for-each select="P">
                        <div>
                            <xsl:attribute name="class">P</xsl:attribute>
                            <xsl:apply-templates select="ancestor-or-self::text()" />
                            <xsl:if test="E">
                                <xsl:for-each select="E">
                                    <span>
                                        <xsl:attribute name="class">emph_Bcol</xsl:attribute>
                                        <xsl:apply-templates select="node()" />
                                    </span>
                                    <xsl:apply-templates select="following-sibling::node()[1]" />
                                </xsl:for-each>
                            </xsl:if>
                        </div>
                    </xsl:for-each>
                </div>
            </xsl:if>
        </div>
    </div>
</xsl:template>

<xsl:template match="FG">
    <div>
        <xsl:attribute name="class">FG</xsl:attribute>
        <xsl:attribute name="id"><xsl:value-of select="@ID"></xsl:value-of>
            </xsl:attribute>
        <xsl:for-each select="P">
            <xsl:if test="FILE">
                <img>
                    <xsl:attribute name="class">center</xsl:attribute>
                    <xsl:attribute name="src">images/<xsl:value-of
                        select="FILE/@NAME" />
                        </xsl:attribute>
                </img>
            </xsl:if>
            <xsl:if test="E">
                <div>
                    <xsl:attribute name="class">caption</xsl:attribute>
                    <xsl:for-each select="E">
                        <span>
                            <xsl:attribute name="class">emph_Bcol</xsl:attribute>
                            <xsl:apply-templates />
                        </span>
                        <xsl:apply-templates select="following-sibling::node()[1]" />
                    </xsl:for-each>
                </div>
            </xsl:if>
        </xsl:for-each>
    </div>
</xsl:template>

<xsl:template match="TB">
    <div>
        <xsl:attribute name="class">TB</xsl:attribute>
        <xsl:attribute name="id"><xsl:value-of select="@ID" /> </xsl:attribute>
        <table>
            <xsl:attribute name="class">FIGURE</xsl:attribute>
            <xsl:attribute name="style">border-collapse:collapse;margin-bottom:1em;</xsl:attribute>
            <tr style="background-color:#0768a9;">
                <td style="vertical-align:top;" class="FIGURE-COL2" colspan="2">
                    <span class="emph_B">
                        <xsl:value-of select="TI/E" />
                    </span>
                    <span class="white">
                        <xsl:value-of select="TI/node()[2]" />
                    </span>
                </td>
            </tr>
            <xsl:apply-templates />
        </table>
    </div>
</xsl:template>

<xsl:template match="TI">
</xsl:template>

<xsl:template match="tr">
    <tr>
        <xsl:apply-templates />
    </tr>
</xsl:template>

<xsl:template match="th">
    <th>
        <xsl:attribute name="style">vertical-align:bottom;text-align:left;</xsl:attribute>
        <xsl:attribute name="rowspan">1</xsl:attribute>
        <xsl:attribute name="colspan">1</xsl:attribute>
        <xsl:choose>
            <xsl:when test="contains(., '&#160;')">
                <xsl:value-of select="translate(., '&#160;', '')" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates />
            </xsl:otherwise>
        </xsl:choose>
    </th>
</xsl:template>

<xsl:template match="td">
    <td>
        <xsl:attribute name="style">vertical-align:top;</xsl:attribute>
        <xsl:attribute name="rowspan">1</xsl:attribute>
        <xsl:attribute name="colspan">1</xsl:attribute>
        <xsl:choose>
            <xsl:when test="contains(., '&#160;')">
                <xsl:value-of select="translate(., '&#160;', '')" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="node()[1]" />
            </xsl:otherwise>
        </xsl:choose>
    </td>
</xsl:template>

Upvotes: 1

Views: 2206

Answers (2)

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22617

This is the way to refer to the first element:

<xsl:variable name="token" select="tokenize(.,': ')[1]"/>

The function substring-before works as well:

<xsl:variable name="token" select="substring-before(.,':')"/>

but since you were asking for an equivalent of last(), [1] is more fitting, I think.

Note that tokenize() takes into consideration the whole string and outputs any tokens that are separated by :. On the other hand, substring-before() returns the substring before the first occurrence of ":". So, this only works if there is always only one ":" in the string, or respectively, if it is always the first ":" that counts.

Judging from your stylesheet it seems that you output both parts of the string (i.e. before and after the ":"). Therefore, it would be a good idea to store the entire tokenization in a variable:

<xsl:variable name="token" select="tokenize(.,': ')"/>

And later refer to $token[1] and $token[2].

EDIT: Edited to respond to your comment. Hope this explains it better:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="E">
  <xsl:variable name="tokens" select="tokenize(.,':')"/>

  <span class="emph_B">
     <span class="emph_bcol">
        <xsl:value-of select="$tokens[1]"/>
     </span>
     <xsl:value-of select="$tokens[2]"/>
  </span>
</xsl:template>

</xsl:stylesheet>

Input

<E T="B">1.1.1-CES: Describe the normal anatomy.</E>

Output

<span class="emph_B">
 <span class="emph_bcol">1.1.1-CES</span> Describe the normal anatomy.</span>

Upvotes: 2

Raul Andres
Raul Andres

Reputation: 3806

substring-before(.,":") will select the string before :

Upvotes: 0

Related Questions