Subject: Re: [xsl] Sorting problem From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Wed, 31 Aug 2005 21:51:49 +1000 |
On 8/31/05, Joe Fawcett <joefawcett@xxxxxxxxxxx> wrote: > David and Dimitre > > Thanks for your advice, I still am missing something about keys though. The > document I showed was obtained midway through a transform by building an RTF > and applying xx:node-set. How then can I define a key based on @type? Exactly as shown in my solution -- an xsl:key defines the relationship node --> key-value regardless of the document in which the node is present. The key() function obtains all the nodes with the specified key-value in the *current document*. In my code this line: > > <xsl:for-each select="$vDoc"> serves the sole purpose of setting the right current document, so that the key() function will return its matching nodes. Cheers, Dimitre Novatchev > > Joe > > > >From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> > >Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > >To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > >Subject: Re: [xsl] Sorting problem > >Date: Wed, 31 Aug 2005 21:36:44 +1000 > > > >On 8/31/05, Joe Fawcett <joefawcett@xxxxxxxxxxx> wrote: > > > Dear All > > > > > > Supposing I have a document such as below => > > > <root> > > > <item type="A" subType="1"/> > > > <item type="A" subType="2"/> > > > <item type="A" subType="4"/> > > > <item type="B" subType="2"/> > > > <item type="B" subType="3"/> > > > <item type="D" subType="1"/> > > > <item type="D" subType="2"/> > > > <item type="D" subType="3"/> > > > <item type="D" subType="4"/> > > > <item type="E" subType="2"/> > > > <item type="E" subType="4"/> > > > </root> > > > > > > This is sorted by @type and then @subType, the subType can be any > >positive > > > number, not just an integer. > > > > > > I need to select the first occurrence of each item, based on its > >@subType, > > > then the second, then the third etc, keeping them in alphabetical order > > > based on @type => > > > > > > <root> > > > <item type="A" subType="1"/> > > > <item type="B" subType="2"/> > > > <item type="D" subType="1"/> > > > <item type="E" subType="2"/> > > > <item type="A" subType="2"/> > > > <item type="B" subType="3"/> > > > <item type="D" subType="2"/> > > > <item type="E" subType="4"/> > > > <item type="A" subType="4"/> > > > <item type="D" subType="3"/> > > > <item type="D" subType="4"/> > > > </root> > > > > > > This is the result of converting a RTF via xx:node-set, I am stuck with > > > version 1.0, so as far as I understand I cannot use keys in the > >solution. > > > > > > > > > I have produced a working solution but it seems inelegant. I first > >select a > > > distinct list of @type using pre-Muenchian methods where the type > >doesn't > > > have a preceding-sibling of the same value. I then call a template by > >name > > > recursively whereby the first pass iterates through the distinct list > >using > > > for-each and selects the the first <item> that matches the type. This > > > template is then called again and does the same for the second matching > >item > > > and continues in the same fashion. The recursion stops after being > >called > > > sufficient times to ensure each item is matched once. > > > > > > Can anyone suggest anything more appealing? > > > > > >This transformation: > > > ><xsl:stylesheet version="1.0" > > xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > > xmlns:msxsl="urn:schemas-microsoft-com:xslt" > > exclude-result-prefixes="msxsl" > > > > > <xsl:output omit-xml-declaration="yes" indent="yes"/> > > > > <xsl:key name="kTypes" match="@type" use="."/> > > <xsl:key name="kItemByType" match="item" use="@type"/> > > > > <xsl:variable name="vDoc" select="/"/> > > > > <xsl:variable name="vrtfdistTypes"> > > <xsl:for-each select= > > "/*/item/@type > > [generate-id() > > = > > generate-id(key('kTypes', .)[1]) > > ]"> > > <type code="{.}" count="{count(key('kTypes', .))}"/> > > </xsl:for-each> > > </xsl:variable> > > > > <xsl:variable name="vdistTypes" > >select="msxsl:node-set($vrtfdistTypes)/*"/> > > > > <xsl:variable name="vmaxCount" > > select="number($vdistTypes[not(@count < > >$vdistTypes/@count)]/@count)"/> > > > > <xsl:variable name="vmaxCountTypecode" > > select="$vdistTypes[not(@count < $vdistTypes/@count)]/@code[1]"/> > > > > <xsl:template match="/"> > > <items> > > <xsl:for-each select="key('kItemByType', $vmaxCountTypecode)"> > > <xsl:variable name="vcurTuple" select="position()"/> > > <xsl:for-each select="$vdistTypes"> > > <xsl:variable name="vthisType" select="."/> > > <xsl:for-each select="$vDoc"> > > <xsl:copy-of select= > > "key('kItemByType', $vthisType/@code)[$vcurTuple]"/> > > </xsl:for-each> > > </xsl:for-each> > > </xsl:for-each> > > </items> > > </xsl:template> > > > ></xsl:stylesheet> > > > >when applied on this source xml: > > > ><root> > > <item type="A" subType="1"/> > > <item type="A" subType="2"/> > > <item type="A" subType="4"/> > > <item type="B" subType="2"/> > > <item type="B" subType="3"/> > > <item type="D" subType="1"/> > > <item type="D" subType="2"/> > > <item type="D" subType="3"/> > > <item type="D" subType="4"/> > > <item type="E" subType="2"/> > > <item type="E" subType="4"/> > ></root> > > > >produces the wanted result: > > > ><items> > > <item type="A" subType="1" /> > > <item type="B" subType="2" /> > > <item type="D" subType="1" /> > > <item type="E" subType="2" /> > > <item type="A" subType="2" /> > > <item type="B" subType="3" /> > > <item type="D" subType="2" /> > > <item type="E" subType="4" /> > > <item type="A" subType="4" /> > > <item type="D" subType="3" /> > > <item type="D" subType="4" /> > ></items> > > > > > >Cheers, > >Dimitre Novatchev. > > -- Cheers, Dimitre Novatchev --------------------------------------- Harry did not ask how Dumbledore knew; ...but Harry had long since learned that bangs and smoke were more often the marks of ineptitude than expertise.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Sorting problem, Joe Fawcett | Thread | Re: [xsl] Sorting problem, Joe Fawcett |
Re: [xsl] Sorting problem, David Carlisle | Date | [xsl] Generate implicit wrapper ele, Rick Quatro |
Month |