Re: [xsl] Speeding up processing (with sablotron or saxon)

Subject: Re: [xsl] Speeding up processing (with sablotron or saxon)
From: "TDarksword" <tdarksword@xxxxxxxxxxxx>
Date: Tue, 13 Jul 2004 18:49:47 +0100
Heyas Wendall,
Possible bug :)

----- Original Message ----- 
From: "Wendell Piez" <wapiez@xxxxxxxxxxxxxxxx>
To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Tuesday, July 13, 2004 4:33 PM
Subject: Re: [xsl] Speeding up processing (with sablotron or saxon)


> Hi Tony,
>
> At 10:57 AM 7/13/2004, you wrote:
>
> >So I'd replace the:-
> ><xsl:for-each
> >select=".//resource[not(@swgcraft_id=preceding::*/@swgcraft_id)]">
> >
> >with
> >
> ><xsl:key name="resource-by-id" match="resource" use="@swgcraft_id"/>
> ><xsl:variable name="resources" select="//resource"/>
> ><xsl:variable name="unique-resources"
> >
select="$resources[not(count(.|key('resources-by-id',@swgcraft_id)[1])
> >= 1)]"/>
> >
> >but I guess I still need some form of for-each statement too?
>
> Yeah, sorry I didn't wrap it up completely -- now you can have
>
> <xsl:for-each select="$unique-resources">...</xsl:for-each>
>
> ...but it will be much more efficient, since the set has already been
> collected -- the processor doesn't now have to look at every resource in
> the document, checking all of their preceding siblings, to establish which
> are unique.
>
> This finding-the-unique-one business ("deduplicating") is one of the
> relatively few common tasks -- maybe the most important -- for which XPath
> 1.0 has no direct provision, requiring us XSLT 1.0 hackers to master a
> couple of tricky idioms.
>
> Another way to do it you may have just seen in another thread. Instead of
>
> <xsl:variable name="unique-resources"
>
select="$resources[not(count(.|key('resources-by-id',@swgcraft_id)[1])
> = 1)]"/>
>
> (Hey! isn't there a glitch here! isn't that 'not' erroneous? Oops ... I
> think I should have offered
> $resources[count(.|key('resources-by-id',@swgcraft_id)[1]) = 1]) ...)
>
> you can have
>
> <xsl:variable name="unique-resources"
>       select="$resources[generate-id() =
> generate-id(key('resources-by-id',@swgcraft_id)[1])]"/>
>
> which does the same thing, but in a different way ... and because of the
> way a string function is defined to work over a node set, can be obscured
> further to simply
>
> $resources[generate-id() =
generate-id(key('resources-by-id',@swgcraft_id))]
>
> Cheers,
> Wendell

using these snippets of code results in nothing coming out of Saxon, and
"Warning: Sablotron error on line 8: XSL element 'key' can only be used at
the top level" error with Sablotron

first bit of code looking like this now

....
<xsl:template match="server" />
<xsl:template match="server[@name='Ahazi']">
<resources>
<xsl:key name="resource-by-id" match="resource" use="@swgcraft_id"/>
<xsl:variable name="resources" select="//resource"/>
<xsl:variable name="unique-resources" select="$resources[generate-id() =
generate-id(key('resources-by-id',@swgcraft_id))]"/>
<xsl:for-each select="$unique-resources">
<xsl:sort select="."/>
<resource>
<xsl:attribute name="swgcraft_id" >
<xsl:value-of select="./@swgcraft_id"/>
</xsl:attribute>
<xsl:copy-of select="name"/>
<xsl:copy-of select="type"/> etc....

I've tried it with each version of <xsl:variable name="unique-resources"
select="$resources.../> you've supplied and they all have the same error.

Tony

Current Thread