This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: xsl:sort problem
- From: Jeni Tennison <jeni at jenitennison dot com>
- To: "Danny Guindi" <Danny dot Guindi at nnu dot com>
- Cc: XSL-List at lists dot mulberrytech dot com
- Date: Mon, 8 Apr 2002 23:15:22 +0100
- Subject: Re: [xsl] xsl:sort problem
- Organization: Jeni Tennison Consulting Ltd
- References: <E6B8B86A81F8AF4482692353A032A980DA3FAB@exchange.nnu.com>
- Reply-to: xsl-list at lists dot mulberrytech dot com
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