I have a xml below
<Report>
<rl>
<id>12345;12346</id>
<activity>a2/a3</activity>
<result>r2/r3</result>
<operator>test</operator>
<timestamp>12/18/2014 3:51:19 PM</timestamp>
<quantity>2</quantity>
</rl>
<rl>
<id>22345;22346</id>
<activity>a3/a4</activity>
<result>r3/r4</result>
<operator>test</operator>
<timestamp>12/18/2014 3:51:19 PM</timestamp>
<quantity>2</quantity>
</rl>
</Report>
and for my xsl,
<table border="1" style="border-width: 1px" width="90%" bordercolor="#C0C0C0" align="center">
<tr>
<th width="5%" align="center">
<font color="#000000" face="Verdana" size="3">Index</font>
</th>
<th width="15%" align="center">
<font color="#000000" face="Verdana" size="3">ID A:</font>
</th>
<th width="15%" align="center">
<font color="#000000" face="Verdana" size="3">ID B:</font>
</th>
</tr>
<xsl:for-each select="Report/rl">
<tr height="25">
<td width="5%" align="center" >
<font color="#000000" face="Verdana" size="2">
<xsl:value-of select="position()" />
</font>
</td>
<td align="center">
<font color="#000000" face="Verdana" size="2">
<xsl:value-of select="idA" />
</font>
</td>
<td align="center">
<font color="#000000" face="Verdana" size="2">
<xsl:value-of select="idB" />
</font>
</td>
</tr>
</xsl:for-each>
</table>
For 1st rl, there is 12345:12346 for tag, I want to split them into 12345 and 12346 and show them in the 'idA' and 'idB'. How should I do that?
My xslt version is 1.0.
Assuming there are always exactly two values, separated by a semicolon, use:
<xsl:value-of select="substring-before(id, ';')"/>
to populate the idA cell, and:
<xsl:value-of select="substring-after(id, ';')"/>
to populate the idB cell.
Added:
For the same example as posted, can you elaborate more about the
'recursive named template'?
The solution using a recursive named template would look something like this:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/Report">
<table border="1">
<tr>
<th>Index</th>
<th>ID A</th>
<th>ID B</th>
</tr>
<xsl:apply-templates select="rl"/>
</table>
</xsl:template>
<xsl:template match="rl">
<tr>
<td>
<xsl:value-of select="position()" />
</td>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="id"/>
</xsl:call-template>
</tr>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="';'"/>
<td>
<xsl:value-of select="substring-before(concat($text, $delimiter), $delimiter)"/>
</td>
<xsl:if test="contains($text, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Note that for the header we assume that the number of columns is known beforehand. Otherwise you'd have to use a similar recursive template to generate the header cells too.
Check this example
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:for-each select="rl">
<node>
<idA>
<xsl:value-of select="substring-before(id,';')"/>
</idA>
<idB>
<xsl:value-of select="substring-after(id,';')"/>
</idB>
</node>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>