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-type
和 order
,但无论我应用哪个变体,我总是得到相同的结果。
我在这里错过了什么?
只有一个名为 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>
我有一个 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-type
和 order
,但无论我应用哪个变体,我总是得到相同的结果。
我在这里错过了什么?
只有一个名为 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>