I am trying to parse the following message string:
"Row 1> testdata1 |Row 5> testdata2 |Row 7> testdata3"
into a HTML table format:
<tr>
<td>Row 1</td><td>testdata1</td>
<td>Row 5</td><td>testdata2</td>
<td>Row 7</td><td>testdata3</td>
</td>
Here is my current attempt:
<xsl:template match="Row">
<tbody><xsl:apply-templates/></tbody>
</xsl:template>
<xsl:template match="col1" >
<xsl:call-template name="parseStr" >
<xsl:with-param name="txt" select="text()" />
</xsl:call-template>
</xsl:template>
<xsl:template name="parseStr">
<xsl:param name="txt" select="''" />
<tr><xsl:choose>
<xsl:when test="contains($txt, '>')" >
<td><xsl:value-of select="substring-before($txt, '>')" /></td><td><xsl:value-of select="substring-after($txt, '>')" /></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="$txt" /></td>
</xsl:otherwise>
</xsl:choose></tr>
<xsl:variable name="leftStr" select="substring-after($txt, '|')" />
<xsl:if test="string-length($leftStr)>1" >
<xsl:call-template name="parseStr" >
<xsl:with-param name="txt" select="$leftStr" />
</xsl:call-template>
</xsl:if>
</xsl:template>
This XSLT provides the correct table structure. I am having difficulties separating the testdata strings after the initial > break.
Output:
<tr>
<td>Row 1</td><td>testdata1 |Row 5> testdata2 |Row 7> testdata3</td>
<td>Row 5</td><td>testdata2 |Row 7> testdata3</td>
<td>Row 7</td><td>testdata 3</td>
</tr>
UPDATE
I’ve figured out how to grab the text inbetween the strings. I added the following:
<td><xsl:value-of select="substring-before($txt, '>')" /></td><td><xsl:value-of select="substring-after(substring-before($txt, '|'), '>')" /></td>
However, I am missing the last parsed message “testdata3”.
Additionally, here is the original XML:
<Rowsets>
<Rowset>
<Row>
<col1>Row 1> testdata1 |Row 5> testdata2 |Row 7> testdata3</col1>
</Row>
</Rowset>
</Rowsets>
UPDATE 2:
success! I figured out the solution to this; however, there may be an easier/cleaner way… here is my solution if you’re interested 🙂
<xsl:template name="parseStr">
<xsl:param name="txt" select="''" />
<tr><xsl:choose>
<xsl:when test="contains($txt, '|')" >
<td><xsl:value-of select="substring-before($txt, '>')" /></td><td><xsl:value-of select="substring-after(substring-before($txt, '|'), '>')"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="substring-before($txt, '>')" /></td><td><xsl:value-of select="substring-after($txt, '>')" /></td>
</xsl:otherwise>
</xsl:choose></tr>
<xsl:variable name="leftStr" select="substring-after($txt, '|')" />
<xsl:if test="string-length($leftStr)>1" >
<xsl:call-template name="parseStr" >
<xsl:with-param name="txt" select="$leftStr" />
</xsl:call-template>
</xsl:if>
</xsl:template>
I. This XSLT 1.0 transformation:
when applied on the this XML document:
produces the wanted, correct result:
II. XSLT 2.0 solution:
this transformation, when applied on the same XML document (above) produces the same correct result: