[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Re: [xsl] sort question
Subject: Re: [xsl] sort question From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Mon, 26 Feb 2001 18:42:09 +0000 |
Hi Kim, > I'm obviously missing something in reading through the sorting > examples available on many web sites. All I want to do is obtain the > same nodes out of the transformation, just sorted. Sort order is > only applied to the KH and Key nodes, the KH nodes sort by the KSort > attribute value and within a KH node, the Key nodes sort by the > KeySort value. No other nodes require sorting, they should remain in > the order they were in originally. I keep getting the same nodes in > the same order they started with from the transformation, I am not > getting a sort applied. Could someone enlighten me as to what I am > missing? You're *so* close. In your template: > <xsl:template match="/"> > <xsl:apply-templates select="Data/KH"> > <xsl:sort select="@KSort" data-type="text" order="ascending"/> > <xsl:sort select="Key[@KeySort]" data-type="text" order="ascending"/> > </xsl:apply-templates> > <xsl:copy-of select="node()"/> > </xsl:template> You apply templates to the KH elements in your Data. The order in which you apply templates is determined by the two sorts; the primary sort is on the KSort attribute of the KH element and the second sort is on the value of the first Key element child of the KH element that has a KeySort attribute. Leaving aside whether that was what you wanted to sort on or not, the main problem is that you are applying templates in this order, but don't have a template to copy the nodes that you're applying templates to! There aren't any templates that match the KH elements (the only template in your stylesheet is the root-node-matching template above), so the built-in templates are used. The built-in templates just give you the string value of the relevant nodes - none of the KH elements have a string value, so you don't get anything from them. Then the last thing you do, after applying templates like this, is to create a complete copy of the node children of the current node. The current node in the template is the root node, so in effect you do a complete copy of the document, giving you exactly what you put in. So, the first thing to do is set up a default template that matches an element and makes a copy of it and its attributes, then moves on recursively, applying templates to its children: <xsl:template match="*"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:apply-templates select="node()" /> </xsl:copy> </xsl:template> Now, when you get down to the Data elements that hold KH elements as children, you want to vary this slightly. Rather than simply applying templates to the KH elements in order, you want to apply them in sorted order. So add the sort that you've currently got in your root-node-matching template to this one instead: <xsl:template match="Data[KH]"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:apply-templates select="KH"> <xsl:sort select="@KSort" /> <xsl:sort select="Key[@KeySort]" /> </xsl:apply-templates> </xsl:copy> </xsl:template> The KH elements will be collected together, sorted, and then have templates applied to them. The KH elements will match the default template above, and so be copied. Now, about the sort. It sounds as if you actually want two levels of sorting - within the Data element, you want the KH elements to be sorted by the KSort attribute, and within the KH elements you want the Key elements to be sorted by the KeySort value. So when a template is applied to a KH element you actually want it to apply templates to its children (the Key elements) in order: <xsl:template match="KH"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:apply-templates select="Key"> <xsl:sort select="@KeySort" /> </xsl:apply-templates> </xsl:copy> </xsl:template> It may be worth amending your Data-matching template to mirror this change by taking out that second, spurious, sort: <xsl:template match="Data[KH]"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:apply-templates select="KH"> <xsl:sort select="@KSort" /> </xsl:apply-templates> </xsl:copy> </xsl:template> Having two xsl:sort elements is useful if, say, you had KH elements that had the same value for their KSort attribute and wanted to sort them according to their KHID or the number of Key elements they contain or something. In other words, its for sorting the *same things* as the primary sort, just on different values. I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] sort question, Hahn, Kimberly | Thread | [xsl] does MSXML3 XT Processor pro, Awasthi, Anand |
Re: [xsl] what is the alternative f, David Carlisle | Date | Re: [xsl] [exsl] Draft 0.1 - call f, David Carlisle |
Month |