transform and sort for selected nodes seems to be not working, for example:
when below XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:next-match/>
<xsl:comment xmlns:saxon="http://saxon.sf.net/">Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}</xsl:comment>
</xsl:template>
<xsl:template match="array">
<xsl:copy>
<xsl:apply-templates select="map">
<xsl:sort select="translate(string[@key='usdt'], '-T:', '')" data-type="number" order="descending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
is applied to the XML:
<map xmlns="http://www.w3.org/2005/xpath-functions">
<map key="msgHeader">
<number key="msgNumber">1</number>
<string key="msgDateTime">2024-05-30T04:43:34.545</string>
<string key="msgAction">mm</string>
</map>
<null key="refId"/>
<null key="associateId"/>
<string key="tt">nn</string>
<string key="iac">oo</string>
<null key="agm"/>
<map key="am">
<string key="ac">nn</string>
<string key="fn">oo</string>
<null key="os"/>
<number key="rias">1</number>
</map>
<null key="dgm"/>
<map key="dm">
<string key="ac">nn</string>
<string key="fn">oo</string>
<null key="os"/>
<number key="rias">1</number>
</map>
<array key="p">
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T04:43:34</string>
</map>
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T10:55:05</string>
</map>
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T03:45:06</string>
</map>
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T18:33:25</string>
</map>
</array>
<array key="t">
<map>
<string key="dps">D1</string>
<string key="sddt">2024-05-30T08:43:34</string>
</map>
<map>
<string key="dps">D1</string>
<string key="sddt">2024-05-30T11:55:05</string>
</map>
<map>
<string key="dps">D1</string>
<string key="sddt">2024-05-30T14:45:06</string>
</map>
<map>
<string key="dps">D1</string>
<string key="sddt">2024-05-30T19:33:25</string>
</map>
</array>
</map>
the result XML should be sorted like:
<array key="p">
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T03:45:06</string>
</map>
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T04:43:34</string>
</map>
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T10:55:05</string>
</map>
<map>
<string key="s">D1</string>
<string key="usdt">2024-05-30T18:33:25</string>
</map>
</array>
Somehow the output is not sorted, Any idea why the sorting is not working in this case? Link to fiddle
You have a namespace issue. You need to add a xpath-default-namespace="http://www.w3.org/2005/xpath-functions"
declaration to your stylesheet, otherwise the <xsl:template match="array">
will not be applied.
And you could probably simplify the code to:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="array">
<xsl:copy>
<xsl:apply-templates select="map">
<xsl:sort select="xs:dateTime(string[@key='usdt'])" order="descending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>