2016-05-16 58 views
0

我有一个XML程序及其首映日期。作为我的XSLT报告的一部分,我想按财政年度(7月1日至6月30日)划分结果。最终的输出结果将显示在Excel电子表格中的不同选项卡上(但这很简单)。 我用Munchean分组来划分我的年份,但是输出结果是基于我的数据中的@year属性,我要么失去第一个或最后一个财政年度,这取决于我的for-each循环。 的示例数据(格式由导出数据库设置):如何按xslt的财政年度分组?

<?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&lt;7]"/> 
    <xsl:key name="kfyear2" use="@year" match="slots/SLOT/schedule_date/DATE[@month&gt;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 &gt; 6)"/> 
        <YEAR> 
         <xsl:text>Financial Year: </xsl:text><xsl:value-of select="$fy"/> 
        </YEAR> 
        <premieres> 
         <xsl:variable name="fy" select="@year + (@month &gt; 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 &gt; 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循环,我得到的财政年2016 & 2017年使用的关键 'kfyear1'。使用关键'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> 

回答

0

你只应该真的需要这里一个键,按财政年度

<xsl:key name="slot_by_year" match="DATE" use="@year + number(@month > 6)" /> 

所以你的日期,两者2016年一年零一个月6,2017年和5个月,“2016年的”slot_by_year“值。

然后为了获得不同的财政年度(通过获得第一次出现的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> 
+0

谢谢蒂姆,这有助于模板的东西。不幸的是,按照书面规定,XSLT将2016年和2017年财政年度合并为一年。 – Hockney

+0

我的歉意。我有六月份开始的财政年度,而不是七月份。我纠正了我的答案! –

+0

啊哈!谢谢蒂姆 - 所以你使用的关键是正确设置财政年度(我试图做但失败),然后祖先把它拉到一起。我需要让我的头绕着xpath轴。 – Hockney