Reputation: 428
I know it is a basic problem but I'm very new to XSL and I don't get it to work. I have a XML-File with a given structure and I want to rearrange the XML in alphabetical order based on one node while keeping the structure. I need that XSLT-Stylesheet to reorder a XML when importing it in Adobe InDesign.
My File:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Employee>
<First_Name>Andrew</First_Name>
<Last_Name>Miller</Last_Name>
<Salary>100000</Salary>
<Performance>8</Performance>
</Employee>
<Employee>
<First_Name>Betsy</First_Name>
<Last_Name>Clarke</Last_Name>
<Salary>105000</Salary>
<Performance>10</Performance>
</Employee>
<Employee>
<First_Name>Donald</First_Name>
<Last_Name>Abernathey</Last_Name>
<Salary>95000</Salary>
<Performance>7</Performance>
</Employee>
</Root>
I want to rearange the document in the way that it is sorted alphabetically based on the tag <Last_name>
. My desired output is:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Employee>
<First_Name>Donald</First_Name>
<Last_Name>Abernathey</Last_Name>
<Salary>95000</Salary>
<Performance>7</Performance>
</Employee>
<Employee>
<First_Name>Betsy</First_Name>
<Last_Name>Clarke</Last_Name>
<Salary>105000</Salary>
<Performance>10</Performance>
</Employee>
<Employee>
<First_Name>Andrew</First_Name>
<Last_Name>Miller</Last_Name>
<Salary>100000</Salary>
<Performance>8</Performance>
</Employee>
</Root>
I found some solutions to re-arange my output but it's always in respect to output HTML and not XML.
Update: As requested here is my atempt to solve the problem. I stuck because it copyies now all in one tag <Employee>
.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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="/">
<Root>
<Employee>
<xsl:for-each select="Root/Employee">
<xsl:sort select="Last_Name"/>
<First_Name><xsl:value-of select="First_Name"/></First_Name>
<Last_Name><xsl:value-of select="Last_Name"/></Last_Name>
<Salary><xsl:value-of select="Salary"/></Salary>
<Performance><xsl:value-of select="Performance"/></Performance>
</xsl:for-each>
</Employee>
</Root>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Views: 976
Reputation: 116992
Or simply:
<xsl:stylesheet version="1.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="/Root">
<xsl:copy>
<xsl:for-each select="Employee">
<xsl:sort select="Last_Name"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 3
Reputation: 167516
If you transform XML to XML where you want to preserve some or even most of the content I would suggest to start with the identity transformation template and then add the templates that are necessary to perform the change you want to make, e.g. in your case to sort:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Root">
<xsl:copy>
<xsl:apply-templates>
<xsl:sort select="Last_Name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/6rexjig
Upvotes: 2
Reputation: 2946
You were really close to the solution:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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="/">
<Root>
<xsl:for-each select="Root/Employee">
<xsl:sort select="Last_Name"/>
<Employee>
<First_Name><xsl:value-of select="First_Name"/></First_Name>
<Last_Name><xsl:value-of select="Last_Name"/></Last_Name>
<Salary><xsl:value-of select="Salary"/></Salary>
<Performance><xsl:value-of select="Performance"/></Performance>
</Employee>
</xsl:for-each>
</Root>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1