Using another code example on stackoverflow we’ve got a paginated print report with headers and footers (yes, that old chestnut) working nicely, doing something like this (where RESULTS_ROW has got multiple child nodes):
<xsl:variable name="n" select="number(4)"/>
<xsl:template match="RESULTS">
<body>
<div id="page">
<output>
<xsl:apply-templates select="RESULTS_ROW"/>
</output>
</div>
</body>
</xsl:template>
<xsl:template match="RESULTS_ROW">
<p/>
[HTML FOR PAGE START]
<br/>
<xsl:for-each select=". | following-sibling::RESULTS_ROW[position() < $n]">
<xsl:value-of select="ITEM43"/><!--Lots more goes in here -->
<br/>
</xsl:for-each>
[HTML FOR PAGE END]
<p/>
</xsl:template>
The problem came with the need to sort RESULTS_ROW on one of its child node values (ITEM43) before the transformation into lumps of 4 elements takes place otherwise the sorting doesn’t take account of all child nodes.
The output is currently something like
[HTML FOR PAGE START]
North
West
North
River
[HTML FOR PAGE END]
[HTML FOR PAGE START]
West
North
River
North
[HTML FOR PAGE END]
Whereas I want the nodes to be completed sorted before they’re split into groups, something like:
[HTML FOR PAGE START]
North
North
North
North
[HTML FOR PAGE END]
[HTML FOR PAGE START]
River
River
West
West
[HTML FOR PAGE END]
I’ve tried everything my not very capable XSL brain can think of but all kinds of sorting, using modes to apply multiple templates to the same node, copying, creating variables containing nodal values etc – nothing seems to work.
Any help would be really appreciated.
EDIT Right, after a bit of determination and checking exactly what
following-siblingdoes I think I’ve got your solution:following-siblingwill always process from the original document, not the order you may have it currently sorted in. This means that when you print out the next 4 nodes, it is taking the next 4 nodes in the original document and not conforming to the sort order.What you need to do is sort the node list before applying your 4 row template (See code sample below).
This now populates the variable
SortedResultswith a string containing a new document, sorted as required. By using thenode-set()you can then convert this back into XML and then apply a template.There is one more problem in your original
RESULTStemplate that affected your results. You were callingapply-templatesover every row so were outputting the next four siblings after each row in the document. This can be resolved with the mod operator shown previously to ensure that the results are only output for every fourth row.Please note the additional namespace that has been added so that the
node-set()extension method could be used.