xslt - Problems pre-sorting xml prior to transforming -
xslt - Problems pre-sorting xml prior to transforming -
using code illustration on stackoverflow we've got paginated print study headers , footers (yes, old chestnut) working nicely, doing (where results_row has got multiple kid 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 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 page end] <p/> </xsl:template>
the problem came need sort results_row on 1 of kid node values (item43) before transformation lumps of 4 elements takes place otherwise sorting doesn't take business relationship of kid nodes.
the output like
[html page start] north west north river [html page end] [html page start] west north river north [html page end]
whereas want nodes completed sorted before they're split groups, like:
[html page start] north north north north [html page end] [html page start] river river west west [html page end]
i've tried not capable xsl brain can think of kinds of sorting, using modes apply multiple templates same node, copying, creating variables containing nodal values etc - nil seems work.
any help appreciated.
edit right, after bit of determination , checking following-sibling
think i've got solution:
following-sibling
process original document, not order may have sorted in. means when print out next 4 nodes, taking next 4 nodes in original document , not conforming sort order.
what need sort node list before applying 4 row template (see code sample below).
this populates variable sortedresults
string containing new document, sorted required. using node-set()
can convert xml , apply template.
there 1 more problem in original results
template affected results. calling apply-templates
on every row outputting next 4 siblings after each row in document. can resolved mod operator shown ensure results output every 4th row.
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:exslt="http://exslt.org/common" extension-element-prefixes="exslt"> <xsl:variable name="n" select="number(4)"/> <xsl:template match="results"> <xsl:variable name="sortedresults"> <xsl:apply-templates select="results_row" mode="sort"> <xsl:sort select="item43"/> </xsl:apply-templates> </xsl:variable> <xsl:variable name="sortedresultsnodeset" select="exslt:node-set($sortedresults)" /> <body> <div id="page"> <output> <xsl:apply-templates select="$sortedresultsnodeset/results_row[position() mod $n = 1]" /> </output> </div> </body> </xsl:template> <xsl:template match="results_row" mode="sort"> <xsl:copy-of select="current()"/> </xsl:template> <xsl:template match="results_row"> <p/> [html page start] <br/> <xsl:for-each select=". | following-sibling::results_row[position() < $n]"> <xsl:value-of select="item43"/> <br/> </xsl:for-each> [html page end] <p/> </xsl:template> </xsl:stylesheet>
please note additional namespace has been added node-set()
extension method used.
xml xslt xpath
Comments
Post a Comment