I have the following XML dataset (simplified), where I can have from zero to endless items (usually there will be 2-10):
<item template="event_element">
<mytitle>This is the first title</mytitle>
<mydate>20110330T143004</mytitle>
<mydescription>This is the first description</mytitle>
<mylink>www.example.com</mytitle>
</item>
.
.
<item template="event_element">
<mytitle>This is the Tenth title</mytitle>
<mydate>20110330T143004</mytitle>
<mydescription>This is the tenth description</mytitle>
<mylink>www.example.com</mytitle>
</item>
My end result should be like this, where I can end up with several sets of items (which will be rotated by javascript):
<div class="body">
<div class="rel" id="arrangement">
// First set of items goes here
<div class="item">
<div class="itm">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>MY DATE</span>
<strong>MY FIRST TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="itm last">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>30. mar 2011</span>
<strong>MY SECOND TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="clr"></div>
</div>
// Second set of items goes here
<div class="item">
<div class="itm">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>MY DATE</span>
<strong>MY THIRD TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="itm last">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>30. mar 2011</span>
<strong>MY FORTH TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="clr"></div>
</div>
<div class="clr"></div>
</div>
My problem is stepping through my items (that should even be sorted by the date desc) and grouping them in sets of two.
As it is today I have been forced to hardcode the sets like this (the $eventfolder, $totalevents variables have been predefined):
<pre><code><div class="body">
<div class="rel" id="arrangement">
<xsl:if test="$totalevents > 0">
<div class="item">
<xsl:for-each select="$eventfolder/item[@template='event_element' and position() > 0 and position() < 3]">
<xsl:choose>
<xsl:when test="position() < $eventsperpage">
<div class="itm">
<xsl:call-template name="renderEvent" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="itm last">
<xsl:call-template name="renderEvent" />
</div>
<div class="clr"></div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</div>
</xsl:if>
<xsl:if test="$totalevents > 2">
<div class="item">
<xsl:for-each select="$eventfolder/item[@template='event_element' and position() > 2 and position() < 5]">
<xsl:choose>
<xsl:when test="position() < $eventsperpage">
<div class="itm">
<xsl:call-template name="renderEvent" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="itm last">
<xsl:call-template name="renderEvent" />
</div>
<div class="clr"></div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</div>
</xsl:if>
<div class="clr"></div>
</div>
</div>
</code></pre>
The renderElement template simply renders the inside event HTML.
But that way is not very practical if I wanted to show more sets than 2 - or even show more items in each set... The xslt file would be big and unreadable...
Any help to how I can solve this problem, since I cant figure out how to insert HTML tags as the XSLT compiler cant see them being closed - ie. (when test="position() = 1
insert html start tag and then later when test="position() = X
close the tag).
Thanks in advance
are you using something similar to this?
Without getting into the larger issues raised by your approach, in XSLT the way to group a list of elements n elements at a time is this:
...which will apply the group-mode template to the first, n+1th, 2n+1th, etc. child elements of the current element. The group-mode template looks like this:
This creates a
group
element, and within that element, applies templates to the current element and its n-1 following siblings.The net effect is that as long as n is a positive integer, the above will create
group
elements containing n consecutive elements from the source tree. In your example, you'd create adiv
instead of agroup
, among other changes.Regarding:
You're thinking about the problem wrong. XSLT generates trees, not tags. You create elements, not halves of elements.
The following stylesheet:
Applied to this input:
Produces the following output:
Change the number of items to include in each group by modifying the value of the
group
variable.