![]() |
|
|
|
#1 |
|
I'm trying to come up with a stylesheet where, when the rows are displayed,
duplicate game names are not shown on subsequent rows. It works but doesn't work properly. If I sort the data using <xsl:sort> prior to processing, it's not checking against the previous row after the sort but instead the previous row from the original data set. Here is the XML and XSL I'm using: <GameSets> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>10th Anniversary</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Anarchs</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Ancient Hearts</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Bloodlines</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Camarilla</setname> </GameSetsRow> <GameSetsRow> <gamename>Netrunner</gamename> <setname>Classic</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Dark Sovereigns</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Final Nights</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Gehenna</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Jyhad</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Kindred Most Wanted</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Legacies of Blood</setname> </GameSetsRow> <GameSetsRow> <gamename>Netrunner</gamename> <setname>Netrunner</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Nights of Reckoning</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Promotional</setname> </GameSetsRow> <GameSetsRow> <gamename>Netrunner</gamename> <setname>Proteus</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Sabbat</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Sabbat War</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>The Black Hand</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>V:TES</setname> </GameSetsRow> </GameSets> <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl <xsl:template match="GameSets"> <html> <head> <title>Game Sets</title> </head> <body> <h1>Game Sets</h1> <table border="1"> <tr> <th>Position</th> <th>Game</th> <th>Set</th> <th>Previous Game</th> </tr> <xsl:for-each select="GameSetsRow"> <xsl:sort select="gamename"/> <xsl:variable name="pos" select="position()"/> <tr> <td><xsl:copy-of select="$pos"/></td> <td> <xsl:if test="$pos = 1 or gamename != preceding-sibling::GameSetsRow[1]/gamename"> <xsl:copy-of select="gamename"/> </xsl:if> </td> <td><xsl:copy-of select="setname"/></td> <td><xsl:copy-of select="preceding-sibling::GameSetsRow[1]/gamename"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> What am I missing? Why isn't the test using the sorted set? thnx, Christoph Christoph |
|
|
|
|
#2 |
|
Posts: n/a
|
>
> What am I missing? Why isn't the test using the sorted set? > The result of <xsl:sort/> is that the current node is selected from the node-list (of xsl:for-each or xsl-apply-templates) in sorted order. This does not change the xml documents and any of the axis relationships between its nodes -- the preceding sibling of any node still remains the same. What you need is to create a completely new document, in which the sorted nodes will indeed be siblings. This can be done if the sorting is performed in the body of an xsl:variable. The resulting variable is of type RTF (Result Tree Fragment) and cannot directly be operated by XPath (except for treating it as a string). One has to convert this RTF to a regular tree by applying the xxx:node-set() extension function on it. The xxx:node-set() ext. fn. is usually provided by the particular XSLT Processor vendor and the prefix "xxx" is typically bound to a vendor-specific namespace. If the XSLT Processor supports EXSLT, then the exslt:node-set() ext. fn. can be used and the xslt code will be portable accross XSLT processors that support EXSLT. In XSLT finding unique nodes is also known as "grouping". More on grouping can be found at: http://www.jenitennison.com/xslt/grouping/ Cheers, Dimitre Novatchev "Christoph" <> wrote in message news:45029257$0$3567$... > I'm trying to come up with a stylesheet where, when the rows are > displayed, duplicate game names are not shown on subsequent rows. It > works but doesn't work properly. If I sort the data using <xsl:sort> > prior to processing, it's not checking against the previous row after the > sort but instead the previous row from the original data set. Here is the > XML and XSL I'm using: > > <GameSets> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>10th Anniversary</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Anarchs</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Ancient Hearts</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Bloodlines</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Camarilla</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Netrunner</gamename> > <setname>Classic</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Dark Sovereigns</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Final Nights</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Gehenna</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Jyhad</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Kindred Most Wanted</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Legacies of Blood</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Netrunner</gamename> > <setname>Netrunner</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Nights of Reckoning</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Promotional</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Netrunner</gamename> > <setname>Proteus</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Sabbat</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>Sabbat War</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>The Black Hand</setname> > </GameSetsRow> > <GameSetsRow> > <gamename>Vampire: The Eternal Struggle</gamename> > <setname>V:TES</setname> > </GameSetsRow> > </GameSets> > > <?xml version="1.0" encoding="UTF-8"?> > <xsl:stylesheet version="1.0" > xmlns > xmlns:fo="http://www.w3.org/1999/XSL/Format"> > <xsl > <xsl:template match="GameSets"> > <html> > <head> > <title>Game Sets</title> > </head> > <body> > <h1>Game Sets</h1> > <table border="1"> > <tr> > <th>Position</th> > <th>Game</th> > <th>Set</th> > <th>Previous Game</th> > </tr> > <xsl:for-each select="GameSetsRow"> > <xsl:sort select="gamename"/> > <xsl:variable name="pos" select="position()"/> > <tr> > <td><xsl:copy-of select="$pos"/></td> > <td> > <xsl:if test="$pos = 1 or gamename != > preceding-sibling::GameSetsRow[1]/gamename"> > <xsl:copy-of select="gamename"/> > </xsl:if> > </td> > <td><xsl:copy-of select="setname"/></td> > <td><xsl:copy-of > select="preceding-sibling::GameSetsRow[1]/gamename"/></td> > </tr> > </xsl:for-each> > </table> > </body> > </html> > </xsl:template> > </xsl:stylesheet> > > What am I missing? Why isn't the test using the sorted set? > > thnx, > Christoph > > > |
|
|
|
#3 |
|
Posts: n/a
|
> extension function on it. The xxx:node-set() ext. fn. is usually provided
> by the particular XSLT Processor vendor and the prefix "xxx" is typically > bound to a vendor-specific namespace. If the XSLT Processor supports > EXSLT, then the exslt:node-set() ext. fn. can be used and the xslt code > will be portable accross XSLT processors that support EXSLT. Is there a XSLT processor that works in both IE and Firefox? > In XSLT finding unique nodes is also known as "grouping". More on grouping > can be found at: > http://www.jenitennison.com/xslt/grouping/ I've read alot about the Muenchian Method alot today while looking into how I might be able to solve this problem. The main thing I've been running into is that it doesn't seem to work properly with a <xsl:sort> sorted data set... Nothing I've tried using this method seemed to do the trick. thnx, Christoph |
|
|
|
#4 |
|
Posts: n/a
|
Christoph wrote:
> Is there a XSLT processor that works in both IE and Firefox? Well, you could write an applet that downloads and runs Xalan... but that's not a particularly efficient solution. If you aren't willing to trust the XSLT processor provided by the browser (or that the browser provides one at all), you may want to do this processing in the server. -- () ASCII Ribbon Campaign | Joe Kesselman /\ Stamp out HTML e-mail! | System architexture and kinetic poetry |
|
|
|
#5 |
|
Posts: n/a
|
"Christoph" <> wrote in message news:45034e03$0$3566$... >> extension function on it. The xxx:node-set() ext. fn. is usually provided >> by the particular XSLT Processor vendor and the prefix "xxx" is typically >> bound to a vendor-specific namespace. If the XSLT Processor supports >> EXSLT, then the exslt:node-set() ext. fn. can be used and the xslt code >> will be portable accross XSLT processors that support EXSLT. > > Is there a XSLT processor that works in both IE and Firefox? > >> In XSLT finding unique nodes is also known as "grouping". More on >> grouping can be found at: >> http://www.jenitennison.com/xslt/grouping/ > > I've read alot about the Muenchian Method alot today while looking into > how I > might be able to solve this problem. The main thing I've been running > into is that > it doesn't seem to work properly with a <xsl:sort> sorted data set... > Nothing I've > tried using this method seemed to do the trick. As I said before, nothing will work if you do not include the sorted nodes in an RTF and transform them to a temporary tree. Then you can perform the Muenchian method on this temporary tree. Cheers, Dimitre Novatchev. > > thnx, > Christoph > |
|
|
|
#6 |
|
Posts: n/a
|
>
> As I said before, nothing will work if you do not include the sorted nodes > in an RTF and transform them to a temporary tree. Then you can perform the > Muenchian method on this temporary tree. > Actually, you'll be able to: 1. Perform the Muenchian method (no sorting is necessary). 2. Do the sorting So, this is a very simple exercise in grouping. This transformation: <xsl:stylesheet version="1.0" xmlns <xsl <xsl:key name="kGN" match="gamename" use="." /> <xsl:template match="/"> <games> <xsl:for-each select= "/*/*/gamename[generate-id() = generate-id(key('kGN',.)[1]) ]"> <xsl:sort/> <xsl:copy-of select=".."/> </xsl:for-each> </games> </xsl:template> </xsl:stylesheet> when applied on your original source xml document: <GameSets> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>10th Anniversary</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Anarchs</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Ancient Hearts</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Bloodlines</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Camarilla</setname> </GameSetsRow> <GameSetsRow> <gamename>Netrunner</gamename> <setname>Classic</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Dark Sovereigns</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Final Nights</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Gehenna</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Jyhad</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Kindred Most Wanted</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Legacies of Blood</setname> </GameSetsRow> <GameSetsRow> <gamename>Netrunner</gamename> <setname>Netrunner</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Nights of Reckoning</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Promotional</setname> </GameSetsRow> <GameSetsRow> <gamename>Netrunner</gamename> <setname>Proteus</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Sabbat</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>Sabbat War</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>The Black Hand</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>V:TES</setname> </GameSetsRow> </GameSets> produces the desired sorted output for all (2 in this case) uniquely named games: <games> <GameSetsRow> <gamename>Netrunner</gamename> <setname>Classic</setname> </GameSetsRow> <GameSetsRow> <gamename>Vampire: The Eternal Struggle</gamename> <setname>10th Anniversary</setname> </GameSetsRow> </games> Hope this helped. Cheers, Dimitre Novatchev "Dimitre Novatchev" <> wrote in message news:4504435c$0$97249$ reenews.net... > > "Christoph" <> wrote in message > news:45034e03$0$3566$... >>> extension function on it. The xxx:node-set() ext. fn. is usually >>> provided by the particular XSLT Processor vendor and the prefix "xxx" is >>> typically bound to a vendor-specific namespace. If the XSLT Processor >>> supports EXSLT, then the exslt:node-set() ext. fn. can be used and the >>> xslt code will be portable accross XSLT processors that support EXSLT. >> >> Is there a XSLT processor that works in both IE and Firefox? >> >>> In XSLT finding unique nodes is also known as "grouping". More on >>> grouping can be found at: >>> http://www.jenitennison.com/xslt/grouping/ >> >> I've read alot about the Muenchian Method alot today while looking into >> how I >> might be able to solve this problem. The main thing I've been running >> into is that >> it doesn't seem to work properly with a <xsl:sort> sorted data set... >> Nothing I've >> tried using this method seemed to do the trick. > > As I said before, nothing will work if you do not include the sorted nodes > in an RTF and transform them to a temporary tree. Then you can perform the > Muenchian method on this temporary tree. > > > Cheers, > Dimitre Novatchev. > >> >> thnx, >> Christoph >> > > |
|
|
|
#7 |
|
Posts: n/a
|
Dimitre Novatchev wrote:
> As I said before, nothing will work if you do not include the sorted nodes > in an RTF and transform them to a temporary tree. Then you can perform the > Muenchian method on this temporary tree. Yep, that's the right approach. -- () ASCII Ribbon Campaign | Joe Kesselman /\ Stamp out HTML e-mail! | System architexture and kinetic poetry |
|