Subject: Re: Grouping, Counting, and Sorting From: "Thomas F. O'Connell" <tfo@xxxxxxxxxxxxxx> Date: Fri, 04 Jun 2004 16:45:41 -0500 |
Okay. I've reworked my original approach somewhat and am closer to a satisfactory solution, but I'm still looking for a little deeper understanding of a few concepts and, even better, a more complete solution. So, now, based on the same example XML provided below, I'm doing this: <table> <th>Header</th> <xsl:apply-templates select="node[valid = 1 and position() <= 100]" /> </table> <xsl:for-each select="node[valid = 1 and position() mod 100=1 and position() > 100]"> <table cellpadding="0" cellspacing="0" border="0"> <xsl:apply-templates select=".|following-sibling::node[valid = 1 and position() < 100]" /> </table> </xsl:for-each> <xsl:for-each select="node[not(valid = 1) and position() mod 100=1 and position() > 100]"> <table cellpadding="0" cellspacing="0" border="0"> <xsl:apply-templates select=".|following-sibling::node[not(valid = 1) and position() < 100]" /> </table> </xsl:for-each> <xsl:template match="node[valid=1]"> <tr> <td class="valid"> <xsl:variable name="number"> <xsl:number value="count(preceding-sibling::output)+1" level="any" format="1" /> </xsl:variable> <xsl:value-of select="$number" />. <xsl:value-of select="data" /> </td> </tr> </xsl:template> <xsl:template match="node[not(valid=1)]"> <tr> <td class="invalid"> <xsl:variable name="number"> <xsl:number value="count(preceding-sibling::output)+1" level="any" format="1" /> </xsl:variable> <xsl:value-of select="$number" />. <xsl:value-of select="data" /> </td> </tr> </xsl:template> The main difference here is that I'm doing selective template application rather than sorting. What I'm discovering, though, is that once all nodes that have a valid node are output, my current method skips any nodes that are not valid until the first complete set of 100 (I.e., where mod 100 = 1). E.g., If I have 150 valid nodes and then 150 invalid nodes, this stylesheet seems to output all 150 valid nodes, skips 50 invalid nodes and then prints the final 100 invalid nodes. I would've thought I could've overcome this by including something along the lines of: <xsl:for-each select="node[not(valid = 1) and position() = count(node[valid = 1]) + 1]"> <table cellpadding="0" cellspacing="0" border="0"> <xsl:apply-templates select=".|following-sibling::node[not(valid = 1) and not(position() mod 100 = 1)]" /> </table> </xsl:for-each> As I understand the grouping, I would've thought this would start with the node whose position was immediately after the last valid node and then iterate until it hit a node with mod 100 = 1, but it doesn't seem to be working. Is my interpretation of how this grouping strategy works correct? What can I do to output these interim nodes successfully (and most appropriately)? Thanks! -tfo > I have some XML that looks like this: > > <data> > <node> > <data>data</data> > <valid>1</valid> > </node> > <node> > <data>data</data> > </node> > </data> > > There can be any number and sequence of nodes. Some nodes are flagged > with a validity node. > > I'm trying to transform it to HTML using XSL. Here are the conditions: > > 1. Group it by 100. > 2. Sort it by whether or not the nodes have a "valid" node (descending > from valid to non-valid, which is just a binary existence check). > 3. The output needs to be numbered sequentially. > 4. The output needs to be formatted differently based on whether a > "valid" node is encountered. > 5. The first chunk of the output needs to include a header. > > Basically, I'm breaking it up into 100-row HTML tables. > > Here's my current approach: > > <table> > <th>Header</th> > <xsl:apply-templates select="node[position() <= 100]"> > <xsl:sort select="valid" /> > </xsl:apply-templates> > </table> > > <xsl:for-each select="node[position() mod 100=1 and position() > > 100]"> > <table cellpadding="0" cellspacing="0" border="0"> > <xsl:apply-templates > select=".|following-sibling::node[position()<100]"> > <xsl:sort select="valid" /> > </xsl:apply-templates> > </table> > </xsl:for-each> > > <xsl:template match="node[valid=1]"> > <tr> > <td class="valid"> > <xsl:variable name="number"> > <xsl:number value="count(preceding-sibling::*)+1" level="any" > format="1" /> > </xsl:variable> > <xsl:value-of select="$number" />. > <xsl:value-of select="data" /> > </td> > </tr> > </xsl:template> > > <xsl:template match="node[not(valid=1)]"> > <tr> > <td class="invalid"> > <xsl:variable name="number"> > <xsl:number value="count(preceding-sibling::*)+1" level="any" > format="1" /> > </xsl:variable> > <xsl:value-of select="$number" />. > <xsl:value-of select="data" /> > </td> > </tr> > </xsl:template> > > Unfortunately, the result of this transformation neither sorts the > output, nor numbers the output sequentially. The grouping works, but I > was under the impression that the sort would apply to the nodes before > their positions were considered. What I understand less is why the sort > does not seem actually to order the nodes correctly in the output. > > Any help is much appreciated. > > Thanks! > > -tfo
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] duplicates result from xs, Norma Yeazell | Thread | Select on Node List Variable, Roger L. Cauvin |
RE: [xsl] duplicates result from xs, Norma Yeazell | Date | Select on Node List Variable, Roger L. Cauvin |
Month |