Reputation: 309
I have a random string like this: 2|TSB;1|NoA;17|IPR;3|RNA;1|NVM;6|OTH;13|UEE
The output need to go in a table like this:
<html xmlns:exsl="http://exslt.org/common">
<head>
</head>
<body>
<table border="1">
<tr>
<td>2</td>
<td>-</td>
<td>TSB</td>
<td></td>
<td></td>
<td>-</td>
<td>OSA</td>
<td></td>
<td>17</td>
<td>-</td>
<td>IP</td>
<td></td>
<td>1</td>
<td>-</td>
<td>NoAgent</td>
<td colspan="4"></td>
</tr>
<tr>
<td></td>
<td>-</td>
<td>LO</td>
<td></td>
<td>13</td>
<td>-</td>
<td>UEE</td>
<td></td>
<td></td>
<td>-</td>
<td>MES</td>
<td></td>
<td>1</td>
<td>-</td>
<td>NoVM</td>
<td colspan="4"></td>
</tr>
<tr>
<td></td>
<td>-</td>
<td>SIT</td>
<td></td>
<td>3</td>
<td>-</td>
<td>RNA</td>
<td></td>
<td></td>
<td>-</td>
<td>NSR</td>
<td></td>
<td></td>
<td>-</td>
<td>ITF</td>
<td>6</td>
<td>-</td>
<td>OTH</td>
</tr>
</table>
</body>
</html>
What creates a table like this
The string has sometimes more information sometimes less. examples are:
Summary: The order in the input string can be random but the output table needs to be as in the provided table.
Listed table has 3 rows with 4 columns of each 3 cells separated by an empty cell but I might want to change this to 4 rows with 3 columns of each 3 cells separated by an empty cell.
The output is created from inside a template. The xsl uses apply and calls several templates to create the output where this table will be part of.
The data is included from an external file like this:
<xsl:apply-templates select="document('file://LocalHost/DATA/DialStatsExamp.xml')" mode="my-mode">
<xsl:with-param name="WGroup" select="$WG" />
<xsl:with-param name="CSII" select="$CurrentShiftInboundInteractions" />
</xsl:apply-templates>
I struggle to extract the concatenated string into the table all attempts made result in a random order of how the parameters are extracted using logic like this:
<xsl:template name="divideSemiColonVariables">
<xsl:param name="to-be-divided"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($to-be-divided,$delimiter)">
<xsl:value-of select="substring-before($to-be-divided,$delimiter)"/>
<xsl:text>,</xsl:text>
<xsl:call-template name="divideSemiColonVariables">
<xsl:with-param name="to-be-divided" select="substring-after($to-be-divided,$delimiter)"/>
<xsl:with-param name="delimiter" select="','"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$to-be-divided"/>
</xsl:otherwise>
</xsl:choose>
Note: The above code is an simplified version of what I use.
Any suggestions of how I could approach this problem in a different way getting the required result would be appreciated.
Upvotes: 1
Views: 111
Reputation: 117073
I couldn't understand how to refer to the input string. In the following example, it is referred to as "yourstring".
The idea here is to tokenize the input string into nodes that can then be called by name. The tokenizing template creates a node-set that looks like this:
<token name="TSB">2</token>
<token name="NoA">1</token>
<token name="IPR">17</token>
<token name="RNA">3</token>
<token name="NVM">1</token>
<token name="OTH">6</token>
<token name="UEE">13</token>
With this in place, you can call the required datum exactly where you need it, simply by:
xsl:value-of select="$data-set[@name='xyz']"/>
Here's an example for the first row of your table:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:variable name="data">
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="yourstring"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="data-set" select="exsl:node-set($data)/token" />
<xsl:template match="/">
<table border="1">
<tr>
<td><xsl:value-of select="$data-set[@name='TSB']"/></td>
<td>-</td>
<td>TSB</td>
<td></td>
<td></td>
<td>-</td>
<td>OSA</td>
<td></td>
<td><xsl:value-of select="$data-set[@name='IPR']"/></td>
<td>-</td>
<td>IP</td>
<td></td>
<td><xsl:value-of select="$data-set[@name='NoA']"/></td>
<td>-</td>
<td>NoAgent</td>
<td colspan="4"></td>
</tr>
<!-- etc. -->
</table>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="string"/>
<xsl:param name="delimiter" select="';'"/>
<xsl:choose>
<xsl:when test="contains($string, $delimiter)">
<xsl:variable name="token" select="substring-before($string, $delimiter)" />
<token name="{substring-after($token, '|')}">
<xsl:value-of select="substring-before($token, '|')"/>
</token>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="substring-after($string, $delimiter)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<token name="{substring-after($string, '|')}">
<xsl:value-of select="substring-before($string, '|')"/>
</token>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1