XSL apply-templates with sorting 不排序

XSL apply-templates with sorting does not sort

我有一个 XML 文档

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <timeperiods>
        <timeperiod>
            <day>1</day>
            <period>1</period>
        </timeperiod>
        <timeperiod>
            <day>1</day>
            <period>2</period>
        </timeperiod>
        <timeperiod>
            <day>2</day>
            <period>1</period>
        </timeperiod>
        <timeperiod>
            <day>2</day>
            <period>2</period>
        </timeperiod>
    </timeperiods>
</document>

我正在按如下方式应用 XSL

<?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"
    exclude-result-prefixes="xs"
    version="2.0">
    
    <xsl:template match="/">
        <xsl:apply-templates select="/document/timeperiods">
            <xsl:sort select="number(period)" data-type="number" order="descending"/>
            <xsl:sort select="number(day)" data-type="number" order="descending"/>
        </xsl:apply-templates>
    </xsl:template>
    
    <xsl:template match="timeperiod">
        <xsl:value-of select="concat(period, '-', day, ' ')"/>
    </xsl:template>
</xsl:stylesheet>

我希望我的模板 timeperiod 会产生 1-1 1-2 2-1 2-2,但它会产生 1-1 2-1 1-2 2-2,这是 XML 文件中的原始顺序。

我尝试了 number() 函数和属性 data-typeorder,但无论我应用哪个变体,我总是得到相同的结果。

我在这里错过了什么?

只有一个名为 timeperiods 的元素,对长度为 1 的序列进行排序将没有用。

您想要对 timeperiod 个元素进行排序,因此您应该对这些元素进行排序 select。您还没有给出 xsl:apply-templates 指令的上下文;显然,这会影响你 select 他们的方式。

要获得您期望的结果,请更改:

    <xsl:apply-templates select="/document/timeperiods">
        <xsl:sort select="number(period)" data-type="number" order="descending"/>
        <xsl:sort select="number(day)" data-type="number" order="descending"/>
    </xsl:apply-templates>

至:

    <xsl:apply-templates select="/document/timeperiods/timeperiod">
        <xsl:sort select="period" data-type="number" order="ascending"/>
        <xsl:sort select="day" data-type="number" order="ascending"/>
    </xsl:apply-templates>

或者简单地做:

XSLT 2.0

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
    
<xsl:template match="/document">
    <xsl:for-each select="timeperiods/timeperiod">
        <xsl:sort select="period" data-type="number" order="ascending"/>
        <xsl:sort select="day" data-type="number" order="ascending"/>
        <xsl:value-of select="period, day" separator="-"/>
        <xsl:text> </xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>