RE: [xsl] sort question

Subject: RE: [xsl] sort question
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 8 Sep 2006 09:06:12 +0100
The key thing about this transformation is that it's a "modified copy". The
"modified copy" pattern is to use an identity template rule, which you've
done:

<xsl:template match="node() | @*">
> 	<xsl:copy>
> 		<xsl:apply-templates select="node() | @*"/>
> 	</xsl:copy>
> </xsl:template>

though I usually use the element-only form:

<xsl:template match="*">
  <xsl:copy>
  <xsl:copy-of select="@*"/>
  <xsl:apply-templates select="*"/>
  </xsl:copy>
</xsl:template>

and then add a template rule for any element whose contents need to change.
That's the segment element:

<xsl:template match="segment">
  <xsl:copy>
  <xsl:apply-templates>
    <xsl:sort select="@xml:lang"/>
  </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

Looking at your code:

 <xsl:template match="/">
>    <xsl:choose>
>   	 <xsl:when test="name() != segment">

Firstly, name() applied to the root node "/" will never be "segment" - the
root node does not have a name. Secondly, an xsl:choose immediately inside
xsl:template, especially when followed by a test on the element name, is a
sure sign that you're not using template rules to their full potential - in
fact you're trying to do the same thing "by hand".

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: Markus Gamperl [mailto:markus.gamperl@xxxxxx]
> Sent: 08 September 2006 07:46
> To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] sort question
>
> Dear experts!
>
> I get for example the following xml:
>
> <pub>
>  <segment>
>   <text xml:lang="en">fdasfds</text>
>   <text xml:lang="de">fdasfds</text>
>   <text xml:lang="fr">fdasfds</text>
>  </segment>
>  <segment>
>   <text xml:lang="fr">fdasfds</text>
>   <text xml:lang="de">fdasfds</text>
>   <text xml:lang="en">fdasfds</text>
>  </segment>
>  <segment>
>   <text xml:lang="fr">fdasfds</text>
>   <text xml:lang="en">fdasfds</text>
>   <text xml:lang="de">fdasfds</text>
>  </segment>
>  ...
> </pub>
>
> For other steps I always need the german (de) then the
> english (en) and at least the french (fr) text.
> I tried to use xsl:sort to sort the xml:lang attribute but I
> don't get it to work :-(
>
> The result for the example xml should look like this:
>
> <pub>
>  <segment>
>   <text xml:lang="de">fdasfds</text>
>   <text xml:lang="en">fdasfds</text>
>   <text xml:lang="fr">fdasfds</text>
>  </segment>
>  <segment>
>   <text xml:lang="de">fdasfds</text>
>   <text xml:lang="en">fdasfds</text>
>   <text xml:lang="fr">fdasfds</text>
>  </segment>
>  <segment>
>   <text xml:lang="de">fdasfds</text>
>   <text xml:lang="en">fdasfds</text>
>   <text xml:lang="fr">fdasfds</text>
>  </segment>
>  ...
> </pub>
>
> I have tried the following stylesheet (and some other combinations):
>
> <xsl:stylesheet ...>
>  <xsl:template match="/">
>    <xsl:choose>
>   	 <xsl:when test="name() != segment">
> 		<xsl:apply-templates select="node() | @*"/>
> 	</xsl:when>
> 	<xsl:otherwise>
> 		<xsl:for-each select="//node()[@xml:lang]">
> 			<xsl:apply-templates select="node() | @*">
> 				<xsl:sort select="@xml:lang"
> order="ascending"/>
> 			</xsl:apply-templates>
> 		</xsl:for-each>
> 		<xsl:apply-templates select="node() | @*"/>
> 	</xsl:otherwise>
>    </xsl:choose>
> </xsl:template>
> 	<!--
> 	-->
> <xsl:template match="node() | @*">
> 	<xsl:copy>
> 		<xsl:apply-templates select="node() | @*"/>
> 	</xsl:copy>
> </xsl:template>
> </xsl:stylesheet>
>
> What's wrong here?
>
> Thanks
> Markus
> --
>
>
> Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
> Ideal f|r Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

Current Thread