XSLT XML to JSON issue

First, you don’t say what version of XSLT you want to use, so here is an XSLT 3.0 solution:

<xsl:stylesheet version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="json" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/r">
        <xsl:map>
            <xsl:variable name="content" as="map(*)*">
                <xsl:apply-templates>
                   <xsl:sort select="xs:date(@Date)"/>
                </xsl:apply-templates>
            </xsl:variable>
            <xsl:map-entry key="'Routes'" select="array{$content}"/>
        </xsl:map>
    </xsl:template>
    <xsl:template match="r/*">
        <xsl:sequence select="map{
            'CO': string(@CO), 
            'Date': string(@Date), 
            'Zone': string(@Zone), 
            'Truck': string(@Truck), 
            'Line':local-name()}"/>
    </xsl:template>
</xsl:stylesheet>

With Saxon this produces the output

{ "Routes": [
    { "CO": "A","Zone": "ASDF","Date": "2022-03-14","Line": "BS","Truck": "BT1" },
    { "CO": "A","Zone": "QWER","Date": "2022-03-14","Line": "GR","Truck": "2TK" },
    { "CO": "B","Zone": "ASDF","Date": "2022-03-15","Line": "GR","Truck": "1TR" }
  ] }

It’s hardly any more difficult with XSLT 1.0 and it’s much easier than you have made it (I really haven’t been able to follow your complex logic at all).

Try this:

<xsl:stylesheet version="1.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/r">
        { "Routes": [
           <xsl:for-each select="*">
            <xsl:sort select="@Date"/>
            <xsl:if test="position() != 1">, </xsl:if>
            {"CO": "<xsl:value-of select="@CO"/>", 
            "Date": "<xsl:value-of select="@Date"/>",
            "Zone": "<xsl:value-of select="@Zone"/>",
            "Truck": "<xsl:value-of select="@Truck"/>", 
            "Line": "<xsl:value-of select="local-name()"/>"}            
           </xsl:for-each>
       ]}
    </xsl:template>

</xsl:stylesheet>

the output is:

    { "Routes": [
       
        {"CO": "A", 
        "Date": "2022-03-14",
        "Zone": "ASDF",
        "Truck": "BT1", 
        "Line": "BS"}           
       , 
        {"CO": "A", 
        "Date": "2022-03-14",
        "Zone": "QWER",
        "Truck": "2TK", 
        "Line": "GR"}           
       , 
        {"CO": "B", 
        "Date": "2022-03-15",
        "Zone": "ASDF",
        "Truck": "1TR", 
        "Line": "GR"}
]}          
       

Read more here: Source link