Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sorting in XLST & output all nodes

Status
Not open for further replies.

majjk

Technical User
Dec 9, 2004
7
GB
I would like to perform something that seems very basic, but I just can't seem to find out how to do it. I have the following document:

<employees>

<employee hireDate="04/23/1999">
<last>Hill</last>
<first>Phil</first>
<salary>100000</salary>
</employee>

<employee hireDate="09/01/1998">
<last>Herbert</last>
<first>Johnny</first>
<salary>95000</salary>
</employee>

<employee hireDate="08/20/2000">
<last>Hill</last>
<first>Graham</first>
<salary>89000</salary>
</employee>

</employees>

and I would like to sort on "salary". I would also like to output all nodes. In this simple example I could of course specify every node I want to output, but I am in a position where I'm not sure which nodes I might have in the future. The only thing I know for sure is that I want to sort on "salary". The following would sort on "salary":

<xsl:stylesheet xmlns:xsl=" version="1.0">

<xsl:eek:utput method="text"/>

<xsl:template match="employees">
<xsl:apply-templates>
<xsl:sort select="salary"/>
</xsl:apply-templates>
</xsl:template>

<xsl:template match="employee">
Last: <xsl:apply-templates select="last"/>
First: <xsl:apply-templates select="first"/>
Salary: <xsl:apply-templates select="salary"/>
Hire Date: <xsl:apply-templates select="@hireDate"/>
<xsl:text>
</xsl:text>

</xsl:template>

</xsl:stylesheet>

but how can I change this so that it will continue to output all info, even if I in the future add more nodes?

To put it in a different way, I just want to transform the document (sort on something) while leaving all info intact. Ideas?
 
Yes. Check out <xsl:copy-of> which will make a deep copy of a node.

Does this have something to do with text output, though?

Tom Morrison
 
No, it is not about any text output. So how would an example of using <xsl:copy-of> with <xsl:sort> look like? Sorry for such a total beginner question, but I simply cannot get it working for some reason. Could you maybe give me some example code?
 
Such as this, replacing the corresponding part.
[tt]
<xsl:template match="employee">
<xsl:for-each select="node()|@*">
<xsl:value-of select="local-name()" />
<xsl:text>:&#x09;</xsl:text>
<xsl:value-of select="." />
<xsl:text>&#x0d;&#x0a;</xsl:text>
</xsl:for-each>
</xsl:template>
[/tt]
 
Here is a start...
Code:
<xsl:template match="/">
<employees>
   <xsl:for-each select="employee">
   <xsl:sort data-type="number" select="salary"/>
      <xsl:copy-of select="."/>
   </xsl:for-each>
</employees>
</xsl:template>
[small][COLOR=red]not tested![/color][/small]

You might be having problems with the context for the xsl:sort.

Tom Morrison
 
Had some time to do it right. Used the input from the original post.
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
<xsl:template match="/">
<employees>
   <xsl:for-each select="employees/employee">
   <xsl:sort data-type="number" select="salary"/>
      <xsl:copy-of select="."/>
   </xsl:for-each>
</employees>	
</xsl:template>
</xsl:stylesheet>
Code:
<employees><employee hireDate="08/20/2000">
    <last>Hill</last>
    <first>Graham</first>
    <salary>89000</salary>
  </employee><employee hireDate="09/01/1998">
    <last>Herbert</last>
    <first>Johnny</first>
    <salary>95000</salary>
  </employee><employee hireDate="04/23/1999">
    <last>Hill</last>
    <first>Phil</first>
    <salary>100000</salary>
  </employee>
</employees>

Here is an alternative XSLT keeping your original technique. The output is identical
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
<xsl:template match="/">
<employees>
   <xsl:apply-templates select="employees/employee">
   <xsl:sort data-type="number" select="salary"/>
   </xsl:apply-templates>
</employees>	
</xsl:template>
<xsl:template match="employee">
      <xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>

Tom Morrison
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top