Although this question has been asked multiples times like here and here before and the answers all seem to work for that particular question, I can't get it to work in my situation.
This xml
<root>
<Orders>
<Order type="S">
<Ref>ABC123</Ref>
<OrderedBy>
<Debtor code="13456"></Debtor>
</OrderedBy>
<DeliveryMethod code="Truck"></DeliveryMethod>
<OrderLine line="1">
<Item code="ABC100400"></Item>
<Quantity>1</Quantity>
</OrderLine>
<OrderLine line="2">
<Item code="XYZ490204" type="S" searchcode="XYZ490204"></Item>
<Quantity>2</Quantity>
</OrderLine>
<OrderLine line="3">
<Item code="DEF1210847" type="S" searchcode="DEF1210847"></Item>
<Quantity>4</Quantity>
</OrderLine>
</Order>
<Order type="S">
<Ref>ABC123</Ref>
<OrderedBy>
<Debtor code="BLABLA" number="802416" type="C"></Debtor>
</OrderedBy>
<DeliveryMethod code="Barefoot"></DeliveryMethod>
<OrderLine line="1">
<Item code="QQQ123456" type="S" searchcode="QQQ123456"></Item>
<Quantity>1</Quantity>
</OrderLine>
<OrderLine line="2">
<Item code="JJJ490204" type="S" searchcode="JJJ490204"></Item>
<Quantity>3</Quantity>
</OrderLine>
</Order>
</Orders>
</root>
needs to be transformed to this xml:
<root>
<Orders>
<Order type="S">
<Ref>ABC123</Ref>
<OrderedBy>
<Debtor code="13456"></Debtor>
</OrderedBy>
<DeliveryMethod code="Truck"></DeliveryMethod>
<OrderLine line="1">
<Item code="ABC100400"></Item>
<Quantity>1</Quantity>
</OrderLine>
<OrderLine line="3">
<Item code="DEF1210847"></Item>
<Quantity>4</Quantity>
</OrderLine>
<OrderLine line="2">
<Item code="XYZ490204"></Item>
<Quantity>2</Quantity>
</OrderLine>
</Order>
<Order type="S">
<Ref>ABC123</Ref>
<OrderedBy>
<Debtor code="BLABLA"></Debtor>
</OrderedBy>
<DeliveryMethod code="Barefoot"></DeliveryMethod>
<OrderLine line="2">
<Item code="JJJ490204"></Item>
<Quantity>3</Quantity>
</OrderLine>
<OrderLine line="1">
<Item code="QQQ123456"></Item>
<Quantity>1</Quantity>
</OrderLine>
</Order>
</Orders>
</root>
What I'm trying to do is for each <Order>
sort the <OrderLine>
elements based on the attributevalue of child <Item>/@code
and also strip some attributes of that child. All the other element outside of OrderLine
need to be left unchanged. Please don't mind the non-optimal structure of the xml, this can't be changed. It probably will take copy, for each combined with sort, like this, but much better:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Orders">
<xsl:copy>
<xsl:apply-templates select="Order/OrderLine/Item|@*">
<xsl:sort select="@code" data-type="text"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
If you want to sort the
OrderLine
elements, you must do so from the context of their parentOrder
:XSLT 1.0
Note: since empty strings sort first, you could shorten the template to:
I didn't see that in your stylesheet. In any case, it's just a matter of adding another template to match
Item
.