Subject: Re: [xsl] Lookup, eliminating duplicates and sorting From: "Manfred Staudinger" <manfred.staudinger@xxxxxxxxx> Date: Sat, 22 Jul 2006 01:25:12 -0700 |
Another perfect solution, I appreciate this very much, thanks again! Manfred
> I'm still fascinated by Dimitre's solution. I also tried a first modification > (but without success): <e1> represents a response from a web service, > but <e2> is supplied by me and fairly static. So it would make sense to > put it in a separate document (teste2.xml), to enable the browser to cache it. > <e2> > <f c="abe" b1="abc"/> > <f c="abf" b1="abj"/> > <f c="abg" b1="abi"/> > <f c="abh" b1="abi"/> > </e2> > The first key definition > <xsl:key name="kb" match="b[not(. = ../../e2/f/@c)]" use="."/> > I assume should become > <xsl:key name="kb" match="b[not(. > =document('teste2.xml')/e2/f/@c)]" use="."/> > but I have no idea how to change the second > <xsl:key name="kb" match="@b1" use="../../../e1/b[. = current()/../@c]"/> > How can I get a xpath expression for the (primary) source document if the > context is in another source document?
Here is the solution to this problem -- it doesn't use any extension functions:
The following transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vdocInput" select="/"/> <xsl:variable name="vdocLookup" select="document('Lookup.xml')"/>
<xsl:key name="kDist" match="b | @b1" use="."/>
<xsl:template match="/">
<xsl:variable name="vOriginal" select= "/*/b[not(. = $vdocLookup/e2/f/@c)]"/>
<xsl:variable name="vunqOriginal" select= "$vOriginal[generate-id() = generate-id(key('kDist', .)[1]) ]" />
<xsl:variable name="vReplaced" select="/*/b[. = $vdocLookup/e2/f/@c]" />
<xsl:variable name="vExternalValues" select= "$vdocLookup/e2/f/@b1 [not(. = $vOriginal)]" />
<xsl:for-each select="$vdocLookup"> <xsl:variable name="vunqAddedValues" select= "$vExternalValues [generate-id() = generate-id(key('kDist',.) [../@c = $vReplaced][1] ) ]" />
<e3> <xsl:for-each select="$vunqOriginal | $vunqAddedValues"> <xsl:sort/>
<b2><xsl:value-of select="."/></b2> </xsl:for-each> </e3> </xsl:for-each> </xsl:template> </xsl:stylesheet>
when applied on this source xml document:
<e1> <b>abc</b> <b>abd</b> <b>abf</b> <b>abe</b> <b>abh</b> <b>abg</b> <b>abd</b> </e1>
and with the following file
Lookup.xml: ========= <e2> <f c="abe" b1="abc"/> <f c="abf" b1="abj"/> <f c="abg" b1="abi"/> <f c="abh" b1="abi"/> </e2>
produces the wanted result:
<e3> <b2>abc</b2> <b2>abd</b2> <b2>abi</b2> <b2>abj</b2> </e3>
-- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence.
On 7/21/06, Manfred Staudinger <manfred.staudinger@xxxxxxxxx> wrote: > On 20/07/06, Mukul Gandhi <gandhi.mukul@xxxxxxxxx> wrote: > > Dimitre's solution is brilliant.. > > > > Here is a solution using the node-set extension function: > Sorry, I didn't state it explicitly, I need xslt 1.0 for browsers (no > extensions), > but thanks anyway. > > On 19/07/06, Dimitre Novatchev <dnovatchev@xxxxxxxxx> wrote: > > > xslt 1.0 - I've a set of nodes, for which I want > > > a. to replace some values (most will not change), then > > > b. eliminate the duplicates and sort them. > > .............................................................................. > > > The text nodes represent URI's and are then used to > > > create html links. So far I was only able to write in > > > 2 different task what should be done in one: > > > > > > > > > One simple way to do this: > > > > The following transformation: > > > > <xsl:stylesheet version="1.0" > > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > > > <xsl:output omit-xml-declaration="yes" indent="yes"/> > > > > <xsl:key name="kb" match="b[not(. = ../../e2/f/@c)]" use="."/> > > <xsl:key name="kb" match="@b1" use="../../../e1/b[. = current()/../@c]"/> > > <xsl:key name="kDist" match="b | @b1" use="."/> > > > > <xsl:template match="/"> > > <e3> > > <xsl:for-each select="key('kb', */e1/b)[generate-id() = > > generate-id(key('kDist', .)[1])]"> > > <xsl:sort/> > > > > <b2><xsl:value-of select="."/></b2> > > </xsl:for-each> > > </e3> > > </xsl:template> > > </xsl:stylesheet> > > > > when applied on the provided source xml document: > > > > <a> > > <e1> > > <b>abc</b> > > <b>abd</b> > > <b>abe</b> > > <b>abf</b> > > <b>abg</b> > > <b>abh</b> > > <b>abd</b> > > </e1> > > <e2> > > <f c="abe" b1="abc"/> > > <f c="abf" b1="abj"/> > > <f c="abg" b1="abi"/> > > <f c="abh" b1="abi"/> > > </e2> > > </a> > > > > produces the wanted result: > > > > <e3> > > <b2>abc</b2> > > <b2>abd</b2> > > <b2>abi</b2> > > <b2>abj</b2> > > </e3> > I'm still fascinated by Dimitre's solution. I also tried a first modification > (but without success): <e1> represents a response from a web service, > but <e2> is supplied by me and fairly static. So it would make sense to > put it in a separate document (teste2.xml), to enable the browser to cache it. > <e2> > <f c="abe" b1="abc"/> > <f c="abf" b1="abj"/> > <f c="abg" b1="abi"/> > <f c="abh" b1="abi"/> > </e2> > The first key definition > <xsl:key name="kb" match="b[not(. = ../../e2/f/@c)]" use="."/> > I assume should become > <xsl:key name="kb" match="b[not(. > =document('teste2.xml')/e2/f/@c)]" use="."/> > but I have no idea how to change the second > <xsl:key name="kb" match="@b1" use="../../../e1/b[. = current()/../@c]"/> > How can I get a xpath expression for the (primary) source document if the > context is in another source document? > Regards, Manfred
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Lookup, eliminating dupli, Dimitre Novatchev | Thread | [xsl] XSLT in IE w/Sarissa - omit-x, Lindsey Simon |
Re: [xsl] Lookup, eliminating dupli, Dimitre Novatchev | Date | Re: [xsl] Multiple Grouping & Muenc, Mukul Gandhi |
Month |