I have a list of elements that I want to split into individual lists of 3. The end result would be something like this:
<ul>
<li>element</li>
<li>element</li>
</ul>
<ul>
<li>element</li>
<li>element</li>
</ul>
<ul>
<li>element</li>
<li>element</li>
</ul>
My XSLT is like this, but it doesn't work, because I can't insert </ul>
, and I can't insert a less than sign (<
).
<ul>
<xsl:for-each select="$myroot/item">
<li></li>
<xsl:if test="position() mod $maxItemsPerColumn = 0">
<!-- I want to close my ul, and start a new one here, but it doesn't work! -->
</xsl:if>
</xsl:for-each>
</ul>
Any ideas? Thanks in advance!
You don't need to do anything fancy like recursion. And good lord, don't even contemplate using CDATA.
You just have to think like XSLT and ask: "What input element do I want to transform into my output element?"
Assuming that each ul
is supposed to contain N item
s, you want to transform every Nth input item
, starting with the first, into a ul
:
<xsl:variable name="n" select="number(4)"/>
<xsl:template match="/">
<output>
<xsl:apply-templates select="/root/item[position() mod $n = 1]"/>
</output>
</xsl:template>
Each of these item
elements becomes a ul
that contains the item and each of its N-1 following siblings:
<xsl:template match="item">
<ul>
<xsl:for-each select=". | following-sibling::item[position() < $n]">
<li>
<xsl:value-of select="."/>
</li>
</xsl:for-each>
</ul>
</xsl:template>
Assuming an input document like this:
<root>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
</root>
...you get this output, if $n
is set to 4:
<output>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
<ul>
<li>9</li>
</ul>
</output>