How can I make the order of all nodes as expected?
The short answer . Using <xsl:apply-templates/>
and <xsl:template>
instead of <xsl:copy-of>
Here is the complete conversion :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="order"> <xsl:copy> <xsl:apply-templates select="customer"/> <xsl:apply-templates select="*[not(self::customer)]"/> </xsl:copy> </xsl:template> <xsl:template match="ship"> <xsl:copy> <xsl:apply-templates select="street"/> <xsl:apply-templates select="city"/> <xsl:apply-templates select="zipcode"/> <xsl:apply-templates select="country"/> </xsl:copy> </xsl:template> <xsl:template match="items"> <xsl:copy> <xsl:apply-templates select="itemno"/> <xsl:apply-templates select="quantity"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
when this conversion is applied to the provided XML document :
<order xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" > <ship> <zipcode>78712</zipcode> <street>1234 Main Street</street> <country>CN</country> <city>Beijing</city> </ship> <items> <quantity>1</quantity> <itemno>1234</itemno> </items> <items> <quantity>3</quantity> <itemno>1235</itemno> </items> <price>456</price> <customer>Tom Hill</customer> </order>
required, the correct result is obtained :
<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <customer>Tom Hill</customer> <ship> <street>1234 Main Street</street> <city>Beijing</city> <zipcode>78712</zipcode> <country>CN</country> </ship> <items> <itemno>1234</itemno> <quantity>1</quantity> </items> <items> <itemno>1235</itemno> <quantity>3</quantity> </items> <price>456</price> </order>
Explanation
<xsl:copy-of select="someElement"/>
copies the entire subtree rooted with someElement
in the same way as (and if we had an instruction that rebuilds the descendants, how will this instruction know the order we want?).
To change the order of siblings, we must specify the new desired order.
This can be done by writing a sequence of <xsl:apply-templates>
instructions, each of which will select the desired element in the right order. We could write <xsl:copy-of>
instructions, but only to copy elements whose descendants we want to leave in their original order.
source share