[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Grouping, Counting, and Sorting

Subject: Re: Grouping, Counting, and Sorting
From: "Thomas F. O'Connell" <tfo@xxxxxxxxxxxxxx>
Date: Fri, 04 Jun 2004 16:45:41 -0500
counting to 100
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() &lt;= 100]" />
</table>

<xsl:for-each select="node[valid = 1 and position() mod 100=1 and position() &gt;
100]">
	<table cellpadding="0" cellspacing="0" border="0">
	<xsl:apply-templates
select=".|following-sibling::node[valid = 1 and position() &lt; 100]" />
	</table>
</xsl:for-each>

<xsl:for-each select="node[not(valid = 1) and position() mod 100=1 and position() &gt;
100]">
	<table cellpadding="0" cellspacing="0" border="0">
	<xsl:apply-templates
select=".|following-sibling::node[not(valid = 1) and position() &lt; 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() &lt;= 100]">
> 	<xsl:sort select="valid" />
> </xsl:apply-templates>
> </table>
> 
> <xsl:for-each select="node[position() mod 100=1 and position() &gt;
> 100]">
> 	<table cellpadding="0" cellspacing="0" border="0">
> 	<xsl:apply-templates
> select=".|following-sibling::node[position()&lt;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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.