Reputation: 79
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'><!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(., ' ')">
<xsl:value-of select="translate(., ' ', '')" />
</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(., ' ')">
<xsl:value-of select="translate(., ' ', '')" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="node()[1]" />
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
Upvotes: 1
Views: 2206
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