I have an XML file with following format:
<DataSet>
<Data id ="1" columns ="4">
<item name ="data1" value="value1"/>
<item name ="data2" value="value2"/>
<item name ="data3" value="value3"/>
<item name ="data4" value="value4"/>
<item name ="data5" value="value5"/>
</Data>
<Data id="2" columns ="2">
<item name ="data1" value="value1"/>
<item name ="data2" value="value2"/>
<item name ="data3" value="value3"/>
<item name ="data4" value="value4"/>
</Data>
</DataSet>
and I need an XSL transformation to get following table structure. Here the idea is to display the name and value attributes in two adjacent cells. So an ‘item’ will be associated with 2 columns and a row will be holding name/value pairs of two items. The number of columns will be specified in the Data element and will be always multiples of 2.
<report>
<table>
<tr>
<td>data1</td>
<td>value1</td>
<td>data2</td>
<td>value2</td>
</tr>
<tr>
<td>data3</td>
<td>value3</td>
<td>data4</td>
<td>value4</td>
</tr>
<tr>
<td>data5</td>
<td>value5</td>
<td></td>
<td></td>
</tr>
</table>
<table>
<tr>
<td>data1</td>
<td>value1</td>
</tr>
<tr>
<td>data2</td>
<td>value2</td>
</tr>
<tr>
<td>data3</td>
<td>value3</td>
</tr>
<tr>
<td>data4</td>
<td>value4</td>
</tr>
</table>
</report>
The following XSL transformation applied to the provided input produces the desired output. Some explanation is provided below.
Matching
/DataSetproduces the root element<report />and continues applying templates.Matching
Datafrom inside/DataSetproduces a<table />for each<Data />element and then starts the interesting part by calling the template namednth-row. The variables and parameters used are:@columnsdivided by two, because each<item />results in two<td />elements.<item />elements present and divided by M. To account fordivtruncating integer values the remainder$count mod $Mis added to$countbefore.Now there come some recursive template calls. Each time
nth-rowis called, it outputs a<tr />and then callsnmth-cellwith appropriate parameters. As long as the current row is not the last one,nth-rowis recursively called with an incremented value of$n.Finally the template
nmth-celleach time it is called outputs two<td />elements containing the values from the appropriate<item />or nothing, if there is no corresponding<item />. As long as the current column is not the last one,nmth-cellis recursively called with an incremented value of$m.I hope this helps. Feel free to ask, if there is anything wrong with this or unclear to you.