Subject: Re: xsl:sort problem
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 8 Apr 2002 23:15:22 +0100
|
Hi Danny,
> When I try to load my XML file I get the following error:
>
> Keyword xsl:apply-templates may not contain xsl:sort.
>
> I don't understand. Everywhere I look it says that xsl:sort can be
> contained in xsl:for-each and xsl:apply-templates. So, what's the
> problem?
You're probably trying to use XSLT with MSXML2, which doesn't support
XSLT. You need to upgrade to MSXML3 or MSXML4, which do support XSLT.
If you're doing client-side transformation in Internet Explorer, you
need MSXML3 installed in replace mode. See the MSXML FAQ at
http://www.netcrucible.com/xslt/msxml-faq.htm.
Even if you use the correct processor, though, I think that you will
have problems with your code:
> <xsl:template match='PEOPLE'>
> <xsl:for-each select='PERSON'>
> <TR>
> <xsl:apply-templates>
> <xsl:sort select='LAST_NAME'/>
> </xsl:apply-templates>
> </TR>
> </xsl:for-each>
> </xsl:template>
This tells the processor that when it finds a PEOPLE element, it
should process each of its child PERSON elements in document order.
For each of those PERSON elements, it should create a TR element. For
the content of that TR element, it should apply templates to the child
nodes of the PERSON element, sorted in alphabetical order based on
their child LAST_NAME element. The kind of structure this implies is:
PEOPLE
+- PERSON
+- some element
+- LAST_NAME
> <xsl:template match='PERSON'>
> <TD><xsl:value-of select='FIRST_NAME'/></TD>
> <TD><xsl:value-of select='LAST_NAME'/></TD>
> <TD><xsl:value-of select='BIRTH_DATE'/></TD>
> </xsl:template>
This template would be used if you ever applies templates to PERSON
elements, which I doubt that you do (although you might, if you have
PERSON elements nested inside each other). Each PERSON element creates
a number of TD elements for the FIRST_NAME, LAST_NAME and BIRTH_DATE
element children of the PERSON element.
I think that what you probably want is to apply templates to the
PERSON elements in the order of their LAST_NAME element children, and
create a TR element for each:
<xsl:template match='PEOPLE'>
<xsl:apply-templates select='PERSON'>
<xsl:sort select='LAST_NAME'/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match='PERSON'>
<TR>
<TD><xsl:value-of select='FIRST_NAME'/></TD>
<TD><xsl:value-of select='LAST_NAME'/></TD>
<TD><xsl:value-of select='BIRTH_DATE'/></TD>
</TR>
</xsl:template>
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|