首页 > 解决方案 > XSLT 2.0/3.0- 选择两条记录并插入缺失的条目

问题描述

我正在处理一个棘手的要求。我有一些包含假期/周末信息的 xml 数据。我需要在两者之间插入缺失的日期(假设缺失的日期是工作日)。

我正在考虑获取第一个日期和最后一个日期,然后对该月的天数运行一个循环,然后插入缺少的天数,但这需要查找月份信息,并且数据中可能包含所有月份。

有没有更快的方法来操作 XSLT 中的日期。

<HOLIDAYS>
        <item>
            <DATE>2020-01-01</DATE>
            <FREEDAY>X</FREEDAY>
            <HOLIDAY/>
            <HOLIDAY_ID/>
            <TXT_SHORT/>
            <TXT_LONG/>
        </item>
        <item>
            <DATE>2020-01-11</DATE>
            <FREEDAY>X</FREEDAY>
            <HOLIDAY/>
            <HOLIDAY_ID/>
            <TXT_SHORT/>
            <TXT_LONG/>
        </item>
        <item>
            <DATE>2020-01-12</DATE>
            <FREEDAY>X</FREEDAY>
            <HOLIDAY/>
            <HOLIDAY_ID/>
            <TXT_SHORT/>
            <TXT_LONG/>
        </item> 
        <item>
            <DATE>2020-01-18</DATE>
            <FREEDAY>X</FREEDAY>
            <HOLIDAY/>
            <HOLIDAY_ID/>
            <TXT_SHORT/>
            <TXT_LONG/>
        </item>
</HOLIDAYS>

output required

<HOLIDAYS>
    <item>
        <DATE>2020-01-01</DATE>
        <FREEDAY/>
        <HOLIDAY/>
        <HOLIDAY_ID/>
        <TXT_SHORT/>
        <TXT_LONG/>
    </item>
    <item>
        <item>
            <DATE>2020-01-02</DATE>
            <FREEDAY/>
            <HOLIDAY/>
            <HOLIDAY_ID/>
            <TXT_SHORT/>
            <TXT_LONG/>
        </item>
        <DATE>2020-01-03</DATE>
        <FREEDAY>X</FREEDAY>
        <HOLIDAY/>
        <HOLIDAY_ID/>
        <TXT_SHORT/>
        <TXT_LONG/>
    </item>
    <item>
        <DATE>2020-01-04</DATE>
        <FREEDAY>X</FREEDAY>
        <HOLIDAY/>
        <HOLIDAY_ID/>
        <TXT_SHORT/>
        <TXT_LONG/>
    </item> 
        
.....       
        
        <item>
        <DATE>2020-01-31</DATE>
        <FREEDAY>X</FREEDAY>
        <HOLIDAY/>
        <HOLIDAY_ID/>
        <TXT_SHORT/>
        <TXT_LONG/>
    </item>
</HOLIDAYS>

标签: xslt

解决方案


正如我在评论中所说,您可以减去xs:dates 以获得持续时间,使用除以一天的持续时间将其转换为“一天”,然后您应该有想要插入新日期的次数:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="item[following-sibling::item]">
      <xsl:next-match/>
      <xsl:apply-templates select="(1 to xs:integer((following-sibling::item[1]/DATE/xs:date(.) - xs:date(DATE)) div xs:dayTimeDuration('P1D')) - 1) ! current()" mode="empty"/>
  </xsl:template>
  
  <xsl:template match="item" mode="empty">
      <xsl:copy>
          <DATE>{xs:date(DATE) + xs:dayTimeDuration('P1D') * position()}</DATE>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

这只插入item带有 newDATE的 s,如果需要,您可以xsl:copy-of select="* except DATE"插入其他元素或插入任何新内容。


推荐阅读