xsl-list
[Top] [All Lists]

Re: Sorting problem

2005-08-31 05:21:35
Dimitre

Thanks, the penny has dropped. I thought that because keys had to be declared at the top level that it had to be valid at all times. I now realise my folly.

Thanks again.

Joe


From: Dimitre Novatchev <dnovatchev(_at_)gmail(_dot_)com>
Reply-To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Sorting problem
Date: Wed, 31 Aug 2005 21:51:49 +1000

On 8/31/05, Joe Fawcett <joefawcett(_at_)hotmail(_dot_)com> 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(_at_)gmail(_dot_)com>
> >Reply-To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
> >To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
> >Subject: Re: [xsl] Sorting problem
> >Date: Wed, 31 Aug 2005 21:36:44 +1000
> >
> >On 8/31/05, Joe Fawcett <joefawcett(_at_)hotmail(_dot_)com> 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.
> >
> >--~------------------------------------------------------------------
> >XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> >To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
> >or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
> >--~--
> >
>
>
>
> --~------------------------------------------------------------------
> XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
> or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
> --~--
>
>


--
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.

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>