I am new to XSLT and I have the requirement of bringing all rows of adjacent HTML tables, having the same structure, in a single table, simply by appending all rows of following tables in the first table encountered:
Input:
<div>
<span class="title">sample</span>
<br/>
some text node1
<br/>
some text node2
<p/>
<table class="class1">
<tbody>
<tr>
<td>L1:</td>
<td>C1</td>
</tr>
</tbody>
</table>
<p/>
<span class="section">Section1</span>
<p/>
<table class="class1">
<tbody>
<tr>
<td>L2:</td>
<td>C2</td>
</tr>
</tbody>
</table>
<table class="class1">
<tbody>
<tr>
<td>L3:</td>
<td>C3</td>
</tr>
</tbody>
</table>
<table class="class1">
<tbody>
<tr>
<td>L4:</td>
<td>C4</td>
</tr>
</tbody>
</table>
<span class="section">Section2</span>
<p/>
<table class="class1">
<tbody>
<tr>
<td>L5:</td>
<td>C5</td>
</tr>
</tbody>
</table>
<table class="class2">
<tbody>
<tr>
<td>L6:</td>
<td>C6</td>
</tr>
</tbody>
</table>
</div>
The resulting output, should merge adjacent tables with @class="class1".
Output:
<div>
<span class="title">sample</span>
<br/>
some text node1
<br/>
some text node2
<p/>
<table class="class1">
<tbody>
<tr>
<td>L1:</td>
<td>C1</td>
</tr>
</tbody>
</table>
<p/>
<span class="section">Section1</span>
<p/>
<table class="class1">
<tbody>
<tr>
<td>L2:</td>
<td>C2</td>
</tr>
<tr>
<td>L3:</td>
<td>C3</td>
</tr>
<tr>
<td>L4:</td>
<td>C4</td>
</tr>
</tbody>
</table>
<span class="section">Section1</span>
<p/>
<table class="class1">
<tbody>
<tr>
<td>L5:</td>
<td>C5</td>
</tr>
</tbody>
</table>
<table class="class2">
<tbody>
<tr>
<td>L6:</td>
<td>C6</td>
</tr>
</tbody>
</table>
</div>
Any ideas how this can be realized? I have been trying to do this using group-adjacent, but I'm not getting the intended result, and I don't know what's missing me.
- Edit:
here is my attempt (NOT WORKING PROPERLY).
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table[@class='class1']">
<xsl:choose>
<xsl:when test="not(preceding-sibling::*[1][self::table])">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="preceding-sibling::*[1]/@class='class1'" />
<xsl:when test="following-sibling::*[1]/@class='class1'" >
<table class="class1">
<tbody>
<xsl:apply-templates select="tbody/*"/>
<xsl:for-each select="following-sibling::*">
<xsl:if test="self::table[@class='class1']">
<xsl:apply-templates select="tbody/*"/>
</xsl:if>
</xsl:for-each>
</tbody>
</table>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
NOTE If possible help me do that both in XSLT1.0, enhancing my attempt, and/or XSLT2.0.
not to disappoint you this time, there was a small change done:
Using XSLT 2.0:
This is a correction of the first version which should ensure that all text nodes containing more than white space are also copied. But it assumes that between those tables you want to group there is solely white space.
Another version using XSLT 2.0