You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用XSLT按TRANNUM列对输出CSV文件进行升序排序?

问题:XSLT转换XML生成CSV时按TRANNUM升序排序的需求

我正在使用XSLT转换XML文件,期望输出的CSV文件按TRANNUM列升序排列,TRANNUM可选值为10、11、12,要求TRANNUM=10的行优先,依次为11、12的行。当前XSLT可正常运行,但实际是按tns:Company/tns:Code(值为RETGP、RTLPM、RETRT)排序,而非TRANNUM值。

待修改的XSLT代码片段

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org"
    xmlns:wd="http://"
    xmlns:tns="http://"
    xmlns:xtt="urn:"
    exclude-result-prefixes="xs math wd tns xtt" version="3.0">
    
    <xsl:param name="p.source"></xsl:param>
    
    <xsl:output method="text" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="tns:OutboundFile">
        <header1>FinJournals&#xD;&#xA;TRANNUM,DATE,PROPERTY,ACCOUNT,POSTMONTH,BOOKNUM,AMOUNT,REMARK,REF,DESC,SEGMENT2,DISPLAYTYPE,ReverseNextMonth</header1>
        <JournalEntry>
            <xsl:for-each-group select="tns:Journal_Entry/tns:Journal_Line[tns:Ledger_Account != '888888']"
                group-by="string-join((tns:Company/tns:Code,tns:Ledger_Account,description),'+')">
            <xsl:sort select="tns:Company/tns:Code" data-type="text" order="ascending"/>
                <xsl:if test="format-number(sum(current-group()/tns:Ledger_Debit_Amount) - sum(current-group()/tns:Ledger_Credit_Amount),'#0.00') != '0.00'">
                    <JournalLine>
                        <xsl:text>&#xD;&#xA;</xsl:text>
                        <TRANNUM>
                            <xsl:choose>
                                <xsl:when test="tns:Company/tns:Code = 'RETGP'">10</xsl:when>
                                <xsl:when test="tns:Company/tns:Code = 'RTLPM'">11</xsl:when>
                                <xsl:when test="tns:Company/tns:Code = 'RETRT'">12</xsl:when>
                            </xsl:choose>
                        </TRANNUM><xsl:text>,</xsl:text>
                        <DATE><xsl:value-of select="format-date(current-date(),'[M01]/[D01]/[Y0001]')"/></DATE><xsl:text>,</xsl:text>
                        <PROPERTY>
                            <xsl:choose>
                                <xsl:when test="tns:Company/tns:Code = 'RETGP'">22000</xsl:when>
                                <xsl:when test="tns:Company/tns:Code = 'RTLPM'">26000</xsl:when>
                                <xsl:when test="tns:Company/tns:Code = 'RETRT'">23000</xsl:when>
                            </xsl:choose>
                        </PROPERTY><xsl:text>,</xsl:text>

当前输出示例

TRANNUM,DATE,PROPERTY,ACCOUNT,POSTMONTH
10,01/11/2023,22000,720010,01/13/2023,1
10,01/11/2023,22000,720025,01/13/2023,1
10,01/11/2023,22000,211070,01/13/2023,1
10,01/11/2023,22000,720005,01/13/2023,1
10,01/11/2023,22000,211070,01/13/2023,1
12,01/11/2023,23000,720025,01/13/2023,1
12,01/11/2023,23000,211070,01/13/2023,1
11,01/11/2023,26000,211070,01/13/2023,1
11,01/11/2023,26000,211010,01/13/2023,1
11,01/11/2023,26000,211065,01/13/2023,1
11,01/11/2023,26000,211010,01/13/2023,1
11,01/11/2023,26000,211070,01/13/2023,1
11,01/11/2023,26000,211015,01/13/2023,1

期望输出示例

TRANNUM,DATE,PROPERTY,ACCOUNT,POSTMONTH
10,01/11/2023,22000,211070,01/13/2023,1
10,01/11/2023,22000,720025,01/13/2023,1
10,01/11/2023,22000,211070,01/13/2023,1
10,01/11/2023,22000,720010,01/13/2023,1
10,01/11/2023,22000,720025,01/13/2023,1
11,01/11/2023,26000,211070,01/13/2023,1
11,01/11/2023,26000,211010,01/13/2023,1
11,01/11/2023,26000,211065,01/13/2023,1
11,01/11/2023,26000,211010,01/13/2023,1
11,01/11/2023,26000,211015,01/13/2023,1
11,01/11/2023,26000,211070,01/13/2023,1
12,01/11/2023,23000,720005,01/13/2023,1
12,01/11/2023,23000,211070,01/13/2023,1

解决方案

问题出在当前的<xsl:sort>是按tns:Company/tns:Code的文本顺序排序,而文本排序中RETRT(对应TRANNUM12)在RTLPM(对应TRANNUM11)之前,导致输出中12的行排在11前面。

只需将原有的排序规则替换为直接映射Code到对应的TRANNUM数值,按数字排序即可:

XSLT 3.0版本(支持choose()函数)

<!-- 替换原来的<xsl:sort> -->
<xsl:sort select="
    choose(
        tns:Company/tns:Code = 'RETGP', 10,
        tns:Company/tns:Code = 'RTLPM', 11,
        tns:Company/tns:Code = 'RETRT', 12
    )" data-type="number" order="ascending"/>

XSLT 2.0及以下版本

<!-- 替换原来的<xsl:sort> -->
<xsl:sort data-type="number" order="ascending">
    <xsl:choose>
        <xsl:when test="tns:Company/tns:Code = 'RETGP'">10</xsl:when>
        <xsl:when test="tns:Company/tns:Code = 'RTLPM'">11</xsl:when>
        <xsl:when test="tns:Company/tns:Code = 'RETRT'">12</xsl:when>
    </xsl:choose>
</xsl:sort>

修改后,分组后的行会按照TRANNUM的数值10→11→12的顺序排列,符合期望输出要求。

内容的提问来源于stack exchange,提问作者Kayode Olanrewaju Mosaku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:35:31