Here is a fraction of the XML data I am processing
<?xml version="1.0" encoding="utf-16"?>
<ScorecardSummary>
<DivisionSummary>
<DivisionName>
<string> SYSTEM</string>
</DivisionName>
<ScorecardSummaryByDivision>
<ScorecardSummaryByKPI>
<Header>
<string>Committed Time of Arrival</string>
<string>Goal</string>
<string>1D</string>
<string>7D</string>
<string>QTD</string>
<string>YTD</string>
<string>YTD Event Cars</string>
</Header>
<Data>
<ScorecardContract>
<TypeName>System</TypeName>
<Goal>68</Goal>
<GoalWarning>64.6</GoalWarning>
<TotalCountYear>1234</TotalCountYear>
<Value1D>79</Value1D>
<Value7D>79.2</Value7D>
<ValueQTD>79.1</ValueQTD>
<ValueYTD>73.3</ValueYTD>
</ScorecardContract>
<ScorecardContract>
<TypeName>AG</TypeName>
<Goal>68</Goal>
<GoalWarning>64.6</GoalWarning>
<TotalCountYear>1111</TotalCountYear>
<Value1D>80.9</Value1D>
<Value7D>78.7</Value7D>
<ValueQTD>78.4</ValueQTD>
<ValueYTD>69.7</ValueYTD>
</ScorecardContract>
This is a small part of the XSL that produces the tables:
<xsl:template match="ScorecardSummary/DivisionSummary/DivisionName">
<h1>
<xsl:value-of select="current()/string"/>
</h1>
</xsl:template>
<xsl:template match="ScorecardSummaryByDivision">
<xsl:apply-templates select="current()/ScorecardSummaryByKPI"/>
</xsl:template>
<xsl:template match="ScorecardSummaryByKPI">
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<xsl:choose>
<xsl:when test="count(preceding-sibling::ScorecardSummaryByKPI) mod 6 < 4">
<td>
<table border="1" cellspacing="0" cellpadding="5">
<xsl:apply-templates select="Header"/>
<xsl:apply-templates select="Data"/>
</table>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<table border="1" cellspacing="0" cellpadding="5">
<xsl:apply-templates select="Header"/>
<xsl:apply-templates select="Data"/>
</table>
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</table>
</xsl:template>
The XSL produces 6 tables repeatedly like this:
1
2
3
4
5
6
1
2
3
4
5
6
But I want to order them like this:
1 4
2 5
3 6
1 4
2 5
3 6
and so on. I tried using this check, but it doesn't work.
count(preceding-sibling::ScorecardSummaryByKPI) mod 6 < 4
Can anyone help?
Explanation
Your table must have two
<td>
per row (if you want two columns). Your XSLT does generate only one.Solution is to interate over one half of the list and generate two
<td>
per iteration.So first I would define a size of the table. Example:
Then iterate over only a half of it (
$size div 2
). The number must be rounded if the input list can contain a non-even number of elements:ceiling($size div 2)
(Rounding up to catch last element)In each iteration, first render an element itself:
Then render an appropriate element from the second half of the table (offset is the number defined before:
ceiling($size div 2)
Half size of the table)You can wrap element rendering in a separate template to avoid code repeating.
Working example
Check this transformation example with W3C XSL TryIt (http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog):
It splits CD-catalog (given in example link above) in two columns.
Perhaps something like this is what you are looking for: (This only shows the idea, you have to adapt it to your input.)
With this short test input xml:
It will generate this output: