need an xslt for a collection control that produces the below:

<ul>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

</ul>

<ul>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

<li>{quicklink}</li>

</ul>

The key here is to have a count on the items. After the 7th item, it needs to start a new list.

Can anybody help with these one..please and Thanks in advance

Dani AI

Generated

Brief recap: wants the collection split into <ul> blocks of 7 items. showed a working recursive XSLT approach and noted the fo:basic-link nodes. The recursive solution is fine, but the sample output shows a trailing empty <ul> — that happens when the template emits a group even when no nodes remain. Two simpler and more robust options follow.

XSLT 1.0 (simple, no recursion)

<xsl:for-each select="/links/fo:basic-link">
  <xsl:if test="(position() mod 7) = 1">
    <ul>
  </xsl:if>

  <li>
    <xsl:value-of select="@external-destination"/>
  </li>

  <xsl:if test="(position() mod 7) = 0 or position() = last()">
    </ul>
  </xsl:if>
</xsl:for-each>

Logic: open a <ul> when the current item is the first in a 7-item block, close it when the position is divisible by 7 or the last item. This avoids the empty final <ul> problem because the close condition covers the last() case.

XSLT 2.0 (cleanest)

<xsl:for-each-group select="/links/fo:basic-link" group-adjacent="(position() - 1) idiv 7">
  <ul>
    <xsl:for-each select="current-group()">
      <li><xsl:value-of select="."/></li>
    </xsl:for-each>
  </ul>
</xsl:for-each-group>

Use this if your processor supports XSLT 2.0 (Saxon 9+). It produces groups directly and is less error-prone.

Extra tips

  • If your nodes are in the FO namespace, declare the same xmlns:fo in the stylesheet or match by local-name()/namespace-uri().
  • If the attribute contains a wrapper like url('http://...'), strip it with substring-before/substring-after before emitting href text.
  • If you keep recursion (as did), add a guard so you only emit a <ul> when the group has at least one node (check count(...) &gt; 0).
  • Test with edge cases (exact multiples of 7, fewer than 7, empty input) to confirm no empty lists are produced.

Recommended Answers

All 3 Replies

It would be helpful if we knew what your input XML document looked like :P Please post a sample of input document (USE CODEBOXES) so we can use it to get your output. Is this XSLT 1.0 ? What processor are you running this on?

<fo:basic-link 
 external-destination="url('http://www.whatever.com')"
 color="blue" text-decoration="underline">
  Webucator
</fo:basic-link>

at as many as you like.

you can put these in tables if you like, they will still be recognized.

as for the after 7 newlist im not sure yet, but you problaly get there using a delimiter and the newlist functions, maybe on a substring?.

Henk.

Well you haven't been very descriptive in your problem at all. So I have no idea if this will help you, or even it it produces what you want. But this is all the help I can give, it should provide you a method/idea to get what you want.

This is a classic grouping issue, which is especially cumbersome in XSLT 1.0. (If you need more information just do a Google search for 'grouping xslt 1.0' and you'll find lots of examples)

My transformation works on via a recursive call template. The idea is that it gathers up all the fo:basic-link element nodes in the input document and passes them into a call template. Inside this call-template, it takes the first 7 element nodes and outputs them inside a <ul> element node. Then it increases the position to the next group of 7, and calls itself. Once it gets to the last group of 7 items or less, it finishes the recursion and doesn't call itself again. Here's all the documents I used to test, the XSLT and the output.

Input Document (since you didn't provide one)

<links xmlns:fo="http://www.w3.org/1999/XSL/Format">
	<fo:basic-link external-destination="url('http://www.whatever1.com')">Webucator1</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator2</fo:basic-link>
	<fo:basic-link external-destination="url('http://www.whatever3.com')">Webucator3</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator4</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator5</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator6</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator7</fo:basic-link>
	<fo:basic-link external-destination="url('http://www.whatever8.com')">Webucator8</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator9</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator10</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator11</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator12</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator13</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator14</fo:basic-link>
	<fo:basic-link external-destination="url('')">Webucator15</fo:basic-link>
	<fo:basic-link external-destination="url('http://www.whatever16.com')">Webucator16</fo:basic-link>
</links>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
	<xsl:output indent="yes"/>

	<xsl:template match="/">
		<html>
			<body>
				<xsl:call-template name="getLinks">
					<xsl:with-param name="setNode" select="/descendant::fo:basic-link"/>
				</xsl:call-template>
			</body>
		</html>
	</xsl:template>

	<xsl:template name="getLinks">
		<xsl:param name="setNode"/>
		<xsl:param name="setPosition" select="1"/>

		<xsl:variable name="setMax" select="count($setNode)"/>

		<xsl:choose>
			<xsl:when test="$setNode">
				<xsl:choose>
					<xsl:when test="(($setMax - $setPosition) &lt;= 0)">
						<ul>
							<xsl:apply-templates select="$setNode[$setPosition]"/>
							<xsl:apply-templates select="$setNode[$setPosition+1]"/>
							<xsl:apply-templates select="$setNode[$setPosition+2]"/>
							<xsl:apply-templates select="$setNode[$setPosition+3]"/>
							<xsl:apply-templates select="$setNode[$setPosition+4]"/>
							<xsl:apply-templates select="$setNode[$setPosition+5]"/>
							<xsl:apply-templates select="$setNode[$setPosition+6]"/>
						</ul>
					</xsl:when>
					<xsl:otherwise>
						<ul>
							<xsl:apply-templates select="$setNode[$setPosition]"/>
							<xsl:apply-templates select="$setNode[$setPosition+1]"/>
							<xsl:apply-templates select="$setNode[$setPosition+2]"/>
							<xsl:apply-templates select="$setNode[$setPosition+3]"/>
							<xsl:apply-templates select="$setNode[$setPosition+4]"/>
							<xsl:apply-templates select="$setNode[$setPosition+5]"/>
							<xsl:apply-templates select="$setNode[$setPosition+6]"/>
						</ul>
						<xsl:call-template name="getLinks">
							<xsl:with-param name="setNode" select="$setNode"/>
							<xsl:with-param name="setPosition" select="$setPosition+7"/>
						</xsl:call-template>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
		</xsl:choose>
	</xsl:template>

	<xsl:template match="fo:basic-link">
		<li>
			<xsl:value-of select="@external-destination"/>
		</li>
	</xsl:template>
</xsl:stylesheet>

Output Document

<html xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <body>
    <ul>
      <li>url('http://www.whatever1.com')</li>
      <li>url('')</li>
      <li>url('http://www.whatever3.com')</li>
      <li>url('')</li>
      <li>url('')</li>
      <li>url('')</li>
      <li>url('')</li>
    </ul>
    <ul>
      <li>url('http://www.whatever8.com')</li>
      <li>url('')</li>
      <li>url('')</li>
      <li>url('')</li>
      <li>url('')</li>
      <li>url('')</li>
      <li>url('')</li>
    </ul>
    <ul>
      <li>url('')</li>
      <li>url('http://www.whatever16.com')</li>
    </ul>
    <ul></ul>
  </body>
</html>
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.