如何在 XSLT 中对连续日期进行分组? [英] How to group consecutive dates in XSLT?
问题描述
我有一个 xml 文件(下面的示例),我想根据连续的 Time_Off_Date 对这个 xml 进行分组.
<块引用><进入><Employee_ID>101</Employee_ID><Time_Off_Details><Time_Off_Date>2017-12-01</Time_Off_Date></Time_Off_Details><Time_Off_Details><Time_Off_Date>2017-12-02</Time_Off_Date></Time_Off_Details><Time_Off_Details><Time_Off_Date>2017-12-04</Time_Off_Date></Time_Off_Details><Time_Off_Details><Time_Off_Date>2017-12-05</Time_Off_Date></Time_Off_Details></条目><进入><Employee_ID>102</Employee_ID><Time_Off_Details><Time_Off_Date>2017-12-10</Time_Off_Date></Time_Off_Details><Time_Off_Details><Time_Off_Date>2017-12-13</Time_Off_Date></Time_Off_Details><Time_Off_Details><Time_Off_Date>2017-12-14</Time_Off_Date></Time_Off_Details></条目></Root>
最终输出应如下所示(CSV 格式).
<块引用>员工 ID 休假开始 休假结束101 12/1/2017 12/2/2017101 12/4/2017 12/5/2017102 12/10/2017 12/10/2017102 12/13/2017 12/14/2017
有没有办法使用 XSLT 2.0 而不使用递归函数来实现这一点?我是 XSLT 的新手,因此不胜感激.
如果逻辑是输入 XML 只保留单独的休息日,并且您想将这些单独的几天(恰好是连续的)分组,那么您可以使用 xsl:for-each-group
选择 Time_Off_Details
并将 group-starting-with
设置为 Time_Off_Date
与前一个元素不连续.
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:xs="http://www.w3.org/2001/XMLSchema"版本=2.0"><xsl:output method="text"/><xsl:strip-space elements="*"/><xsl:template match="条目"><xsl:for-each-group select="Time_Off_Details"group-starting-with="*[not(xs:date(Time_Off_Date) = xs:date(preceding-sibling::*[1]/Time_Off_Date) + xs:dayTimeDuration('P1D'))]"><xsl:value-of select="../Employee_ID"/><xsl:text>,</xsl:text><xsl:value-of select="Time_Off_Date"/><xsl:text>,</xsl:text><xsl:value-of select="current-group()[last()]/Time_Off_Date"/><xsl:text> </xsl:text></xsl:for-each-group></xsl:模板></xsl:stylesheet>
I have an xml file (sample below) and I want to group this xml based on consecutive Time_Off_Date.
<Root> <Entry> <Employee_ID>101</Employee_ID> <Time_Off_Details> <Time_Off_Date>2017-12-01</Time_Off_Date> </Time_Off_Details> <Time_Off_Details> <Time_Off_Date>2017-12-02</Time_Off_Date> </Time_Off_Details> <Time_Off_Details> <Time_Off_Date>2017-12-04</Time_Off_Date> </Time_Off_Details> <Time_Off_Details> <Time_Off_Date>2017-12-05</Time_Off_Date> </Time_Off_Details> </Entry> <Entry> <Employee_ID>102</Employee_ID> <Time_Off_Details> <Time_Off_Date>2017-12-10</Time_Off_Date> </Time_Off_Details> <Time_Off_Details> <Time_Off_Date>2017-12-13</Time_Off_Date> </Time_Off_Details> <Time_Off_Details> <Time_Off_Date>2017-12-14</Time_Off_Date> </Time_Off_Details> </Entry> </Root>
The final output should look like this (in CSV format).
Employee ID Time Off Start Time Off End 101 12/1/2017 12/2/2017 101 12/4/2017 12/5/2017 102 12/10/2017 12/10/2017 102 12/13/2017 12/14/2017
Is there a way to achieve this using XSLT 2.0 and without using recursive functions?? I am new to XSLT so any advice is appreciated.
If the logic is that the input XML only holds individual days off and you want to group these individual days where they happen to be consecutive, then you can use xsl:for-each-group
to select the Time_Off_Details
with the group-starting-with
set to the elements where the Time_Off_Date
is not consecutive with the previous element.
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0">
<xsl:output method="text" />
<xsl:strip-space elements="*" />
<xsl:template match="Entry">
<xsl:for-each-group select="Time_Off_Details"
group-starting-with="*[not(xs:date(Time_Off_Date) = xs:date(preceding-sibling::*[1]/Time_Off_Date) + xs:dayTimeDuration('P1D'))]">
<xsl:value-of select="../Employee_ID" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Time_Off_Date" />
<xsl:text>,</xsl:text>
<xsl:value-of select="current-group()[last()]/Time_Off_Date" />
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
这篇关于如何在 XSLT 中对连续日期进行分组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!