如何在 xslt 中按财政年度分组?
How do I group by financial year in xslt?
我有 XML 个节目及其首映日期。作为我的报告 XSLT 的一部分,我想按财政年度(7 月 1 日 - 6 月 30 日)划分结果。最终输出将输出到 excel 电子表格中的不同选项卡(但这很简单)。
我使用 Munchean 分组来划分我的年份,但输出基于我数据中的 @year 属性,我要么丢失第一个财政年度,要么丢失最后一个财政年度,具体取决于我的 for-each 循环。
示例数据(格式由导出数据库设置):
<?xml version="1.0" encoding="UTF-8"?>
<slots>
<SLOT oid="3229327812">
<schedule_date>
<DATE year="2016" month="6" day="1" monthname="June" dateindays="42155"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Amber Anchor"/>
</programme>
</SLOT>
<SLOT oid="3229327813">
<schedule_date>
<DATE year="2016" month="6" day="30" monthname="June" dateindays="42184"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Big Bang"/>
</programme>
</SLOT>
<SLOT oid="3229327815">
<schedule_date>
<DATE year="2016" month="7" day="30" monthname="July" dateindays="42214"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Car Crash"/>
</programme>
</SLOT>
<SLOT oid="3229327814">
<schedule_date>
<DATE year="2016" month="7" day="1" monthname="July" dateindays="42185"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 2"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Deep Dodo"/>
</programme>
</SLOT>
<SLOT oid="3229327815">
<schedule_date>
<DATE year="2017" month="1" day="5" monthname="January" dateindays="42365"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 2"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Eerie Earl"/>
</programme>
</SLOT>
<SLOT oid="3229327815">
<schedule_date>
<DATE year="2017" month="7" day="5" monthname="July" dateindays="42531"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Fall Flat"/>
</programme>
</SLOT>
</slots>
XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kfyear1" use="@year" match="slots/SLOT/schedule_date/DATE[@month<7]"/>
<xsl:key name="kfyear2" use="@year" match="slots/SLOT/schedule_date/DATE[@month>6]"/>
<xsl:template match="/">
<body>
<FinancialYear>
<!--<xsl:for-each select="/slots/SLOT/schedule_date/DATE[generate-id() = generate-id(key('kfyear1',@year)[1])]">-->
<xsl:for-each select="/slots/SLOT/schedule_date/DATE[generate-id() = generate-id(key('kfyear2',@year)[1])]">
<xsl:variable name="fy" select="@year + (@month > 6)"/>
<YEAR>
<xsl:text>Financial Year: </xsl:text><xsl:value-of select="$fy"/>
</YEAR>
<premieres>
<xsl:variable name="fy" select="@year + (@month > 6)"/>
<xsl:call-template name="FinYear">
<xsl:with-param name="fyr" select="$fy"/>
</xsl:call-template>
</premieres>
</xsl:for-each>
</FinancialYear>
</body>
</xsl:template>
<xsl:template name="FinYear">
<xsl:param name="fyr"/>
<xsl:for-each select="/slots/SLOT[(schedule_date/DATE/@year+(schedule_date/DATE/@month > 6)=$fyr)]">
<PREMIERE>
<xsl:value-of select="schedule_channel/CHANNEL/@name"/><xsl:text>: </xsl:text>
<xsl:value-of select="programme/PROG_DETAIL/@prog_title"/><xsl:text>: </xsl:text>
<xsl:value-of select="schedule_date/DATE/@day"/><xsl:text> </xsl:text>
<xsl:value-of select="schedule_date/DATE/@monthname"/><xsl:text> </xsl:text>
<xsl:value-of select="schedule_date/DATE/@year"/>
</PREMIERE>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在我的 for-each 循环中使用键 'kfyear1',我得到 2016 和 2017 财政年度。使用键 'kfyear2',我得到 2017 和 2018 财政年度。我如何获得所有三个财政年度?
我怀疑我需要放弃 for-each 循环并使用模板完成所有操作,但我不知道如何做。
编辑:添加预期结果:
<?xml version="1.0"?>
<body>
<FinancialYear>
<YEAR>2016</YEAR>
<premieres>
<PREMIERE>Channel 1: Amber Anchor: 1 June 2016</PREMIERE>
<PREMIERE>Channel 1: Big Bang: 30 June 2016</PREMIERE>
</premieres>
</FinancialYear>
<FinancialYear>
<YEAR>2017</YEAR>
<premieres>
<PREMIERE>Channel 1: Car Crash: 30 July 2016</PREMIERE>
<PREMIERE>Channel 2: Deep Dodo: 1 July 2016</PREMIERE>
<PREMIERE>Channel 2: Eerie Earl: 5 January 2017</PREMIERE>
</premieres>
</FinancialYear>
<FinancialYear>
<YEAR>2018</YEAR>
<premieres>
<PREMIERE>Channel 1: Fall Flat: 5 July 2017</PREMIERE>
</premieres>
</FinancialYear>
</body>
您在这里只需要一个键,即可按财政年度对您的日期进行分组
<xsl:key name="slot_by_year" match="DATE" use="@year + number(@month > 6)" />
因此,2016 年和 6 月以及 2017 年和 5 月的 "slot_by_year" 值为 2016。
然后要获得不同的财政年度,(通过获得每个财政年度第一次出现的 DATE
)你可以这样做
<xsl:for-each select="SLOT/schedule_date/DATE[generate-id() = generate-id(key('slot_by_year', @year + number(@month > 6))[1])]">
然后要获取本财政年度内的 SLOT
元素,您可以这样做(其中 $fy
设置为当前财政年度)
<xsl:apply-templates select="key('slot_by_year', $fy)/ancestor::SLOT"/>
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="slot_by_year" match="DATE" use="@year + number(@month > 6)" />
<xsl:template match="/slots">
<body>
<xsl:for-each select="SLOT/schedule_date/DATE[generate-id() = generate-id(key('slot_by_year', @year + number(@month > 6))[1])]">
<xsl:variable name="fy" select="@year + number(@month > 6)"/>
<financial_year>
<YEAR><xsl:value-of select="$fy" /></YEAR>
<premieres>
<xsl:apply-templates select="key('slot_by_year', $fy)/ancestor::SLOT"/>
</premieres>
</financial_year>
</xsl:for-each>
</body>
</xsl:template>
<xsl:template match="SLOT">
<PREMIERE>
<xsl:value-of select="schedule_channel/CHANNEL/@name"/>
<xsl:text>: </xsl:text>
<xsl:value-of select="programme/PROG_DETAIL/@prog_title"/>
</PREMIERE>
</xsl:template>
</xsl:stylesheet>
我有 XML 个节目及其首映日期。作为我的报告 XSLT 的一部分,我想按财政年度(7 月 1 日 - 6 月 30 日)划分结果。最终输出将输出到 excel 电子表格中的不同选项卡(但这很简单)。 我使用 Munchean 分组来划分我的年份,但输出基于我数据中的 @year 属性,我要么丢失第一个财政年度,要么丢失最后一个财政年度,具体取决于我的 for-each 循环。 示例数据(格式由导出数据库设置):
<?xml version="1.0" encoding="UTF-8"?>
<slots>
<SLOT oid="3229327812">
<schedule_date>
<DATE year="2016" month="6" day="1" monthname="June" dateindays="42155"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Amber Anchor"/>
</programme>
</SLOT>
<SLOT oid="3229327813">
<schedule_date>
<DATE year="2016" month="6" day="30" monthname="June" dateindays="42184"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Big Bang"/>
</programme>
</SLOT>
<SLOT oid="3229327815">
<schedule_date>
<DATE year="2016" month="7" day="30" monthname="July" dateindays="42214"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Car Crash"/>
</programme>
</SLOT>
<SLOT oid="3229327814">
<schedule_date>
<DATE year="2016" month="7" day="1" monthname="July" dateindays="42185"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 2"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Deep Dodo"/>
</programme>
</SLOT>
<SLOT oid="3229327815">
<schedule_date>
<DATE year="2017" month="1" day="5" monthname="January" dateindays="42365"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 2"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Eerie Earl"/>
</programme>
</SLOT>
<SLOT oid="3229327815">
<schedule_date>
<DATE year="2017" month="7" day="5" monthname="July" dateindays="42531"/>
</schedule_date>
<schedule_channel>
<CHANNEL name="Channel 1"/>
</schedule_channel>
<programme>
<PROG_DETAIL prog_title="Fall Flat"/>
</programme>
</SLOT>
</slots>
XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kfyear1" use="@year" match="slots/SLOT/schedule_date/DATE[@month<7]"/>
<xsl:key name="kfyear2" use="@year" match="slots/SLOT/schedule_date/DATE[@month>6]"/>
<xsl:template match="/">
<body>
<FinancialYear>
<!--<xsl:for-each select="/slots/SLOT/schedule_date/DATE[generate-id() = generate-id(key('kfyear1',@year)[1])]">-->
<xsl:for-each select="/slots/SLOT/schedule_date/DATE[generate-id() = generate-id(key('kfyear2',@year)[1])]">
<xsl:variable name="fy" select="@year + (@month > 6)"/>
<YEAR>
<xsl:text>Financial Year: </xsl:text><xsl:value-of select="$fy"/>
</YEAR>
<premieres>
<xsl:variable name="fy" select="@year + (@month > 6)"/>
<xsl:call-template name="FinYear">
<xsl:with-param name="fyr" select="$fy"/>
</xsl:call-template>
</premieres>
</xsl:for-each>
</FinancialYear>
</body>
</xsl:template>
<xsl:template name="FinYear">
<xsl:param name="fyr"/>
<xsl:for-each select="/slots/SLOT[(schedule_date/DATE/@year+(schedule_date/DATE/@month > 6)=$fyr)]">
<PREMIERE>
<xsl:value-of select="schedule_channel/CHANNEL/@name"/><xsl:text>: </xsl:text>
<xsl:value-of select="programme/PROG_DETAIL/@prog_title"/><xsl:text>: </xsl:text>
<xsl:value-of select="schedule_date/DATE/@day"/><xsl:text> </xsl:text>
<xsl:value-of select="schedule_date/DATE/@monthname"/><xsl:text> </xsl:text>
<xsl:value-of select="schedule_date/DATE/@year"/>
</PREMIERE>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在我的 for-each 循环中使用键 'kfyear1',我得到 2016 和 2017 财政年度。使用键 'kfyear2',我得到 2017 和 2018 财政年度。我如何获得所有三个财政年度? 我怀疑我需要放弃 for-each 循环并使用模板完成所有操作,但我不知道如何做。
编辑:添加预期结果:
<?xml version="1.0"?>
<body>
<FinancialYear>
<YEAR>2016</YEAR>
<premieres>
<PREMIERE>Channel 1: Amber Anchor: 1 June 2016</PREMIERE>
<PREMIERE>Channel 1: Big Bang: 30 June 2016</PREMIERE>
</premieres>
</FinancialYear>
<FinancialYear>
<YEAR>2017</YEAR>
<premieres>
<PREMIERE>Channel 1: Car Crash: 30 July 2016</PREMIERE>
<PREMIERE>Channel 2: Deep Dodo: 1 July 2016</PREMIERE>
<PREMIERE>Channel 2: Eerie Earl: 5 January 2017</PREMIERE>
</premieres>
</FinancialYear>
<FinancialYear>
<YEAR>2018</YEAR>
<premieres>
<PREMIERE>Channel 1: Fall Flat: 5 July 2017</PREMIERE>
</premieres>
</FinancialYear>
</body>
您在这里只需要一个键,即可按财政年度对您的日期进行分组
<xsl:key name="slot_by_year" match="DATE" use="@year + number(@month > 6)" />
因此,2016 年和 6 月以及 2017 年和 5 月的 "slot_by_year" 值为 2016。
然后要获得不同的财政年度,(通过获得每个财政年度第一次出现的 DATE
)你可以这样做
<xsl:for-each select="SLOT/schedule_date/DATE[generate-id() = generate-id(key('slot_by_year', @year + number(@month > 6))[1])]">
然后要获取本财政年度内的 SLOT
元素,您可以这样做(其中 $fy
设置为当前财政年度)
<xsl:apply-templates select="key('slot_by_year', $fy)/ancestor::SLOT"/>
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="slot_by_year" match="DATE" use="@year + number(@month > 6)" />
<xsl:template match="/slots">
<body>
<xsl:for-each select="SLOT/schedule_date/DATE[generate-id() = generate-id(key('slot_by_year', @year + number(@month > 6))[1])]">
<xsl:variable name="fy" select="@year + number(@month > 6)"/>
<financial_year>
<YEAR><xsl:value-of select="$fy" /></YEAR>
<premieres>
<xsl:apply-templates select="key('slot_by_year', $fy)/ancestor::SLOT"/>
</premieres>
</financial_year>
</xsl:for-each>
</body>
</xsl:template>
<xsl:template match="SLOT">
<PREMIERE>
<xsl:value-of select="schedule_channel/CHANNEL/@name"/>
<xsl:text>: </xsl:text>
<xsl:value-of select="programme/PROG_DETAIL/@prog_title"/>
</PREMIERE>
</xsl:template>
</xsl:stylesheet>