Here's one way to do it. But note that I had to guess about your input
file. See below of what I tried as input.
<xsl:output indent="yes"/>
<xsl:template match="B">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="C">
<xsl:sort select="D" data-type="number" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
A couple of things to notice:
1. Choosing xsl:for-each instead of xsl:apply-templates is like
choosing between buckles or laces for your shoes. But to many people
(including myself) it is also choosing between GOTO (1960) and FUNCTION
(1970). But rest assured: xsl:for-each is a misguided
xsl:apply-templates (and it is *not* a loop, contrary to its name).
2. There are situations where xsl:for-each is preferred, notably
when the selection does not contain a sequence of nodes (you can't
apply-templates on a sequence of strings.
3. You do not need to state that you want output of
xml/utf-8/version 1.0, these are all the default.
4. You can apply an xsl:sort on for-each, for-each-group and
apply-templates, no need to use for-each.
5. My approach does not do exactly the same as your approach.
Depending on your real source data, it may need some tweaking.
It is good to learn about XSLT and about how to use xsl:apply-templates
and matching templates. It will speed up your XSLT development
dramatically once you get used to it. A good tutorial or a good teacher
is usually all that it takes, and a few hours time of course. Once you
get used to it, it is quite easy, really and you quickly forget about
xsl:for-each.
Good luck coding,
Cheers,
-- Abel Braaksma
PS, this is the sample data I used:
<A>
<B>
<C name="x">
<abc>some rubbish</abc>
<D>5</D>
<xyz>other rubbish here</xyz>
</C>
<C name="y">
<abc>some rubbish</abc>
<D>2</D>
<xyz>other rubbish here</xyz>
</C>
<C name="z">
<abc>some rubbish</abc>
<D>12</D>
</C>
<C name="zz">
<abc>some rubbish</abc>
<D>3</D>
<xyz>other rubbish here</xyz>
</C>
</B>
</A>
Danny Leblanc wrote:
Good day everyone,
I have read in the past here that most people who are not "used" to XSLT tend
to use for-each when an apply template would be the better route. I have received the
following XSLT file.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<A>
<B>
<xsl:for-each select="/A/B/C">
<xsl:sort order = "ascending" data-type = "number" select = "D"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</B>
</A>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
In a case like this, would there be a better way to handle this using apply
templates? Would there be a performance gain by using apply templates instead?
I tried to put one together but to date have not had much success but just
wanted to ensure that switching to apply templates would be the correct way to
go.
Thank you for all advice given.
Danny
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--