根据 xslt 中的连续日期元素和时间类型生成唯一事件 ID
Generating unique event ID based on consecutive dated element and time type in xslt
希望你们 well.Thank 非常感谢你们 advance.Your 的帮助。
在为以下内容创建 XSLT (v2.0) 时遇到了麻烦requirement.Not 了解如何实现它。
要求:
根据每位员工的协商日期和时间类型生成唯一的事件 ID。
示例: 对于员工 EMP12345 正在休年假,日期为 2015-03-31,病假时间为 2015-04- 01 至 2015-04-03 和 2015-04-15 至 2015-04-16.
所以有2个连续日期的病假。所以需要生成两个唯一的事件id。
请参考以下预期输出。
XML
<?xml version='1.0' encoding='UTF-8'?>
<Data>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Annual</Time_type>
<Date>2015-03-31</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-01</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-02</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-03</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-15</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-16</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12346</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-01</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12346</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-02</Date>
<Hours>6</Hours>
</Employee>
</Data>
预期输出:
Employee ID,Time Type,Date,Hours,Event ID
EMP12345,Annual,2015-03-31,6,
EMP12345,Sick,2015-04-01,6,12344EMP12345
EMP12345,Sick,2015-04-02,6,12344EMP12345
EMP12345,Sick,2015-04-03,6,12344EMP12345
EMP12345,Sick,2015-04-15,6,22344EMP12345
EMP12345,Sick,2015-04-16,6,22344EMP12345
EMP12346,Sick,2015-04-01,6,11111EMP12346
EMP12346,Sick,2015-04-02,6,11111EMP12346
谢谢,
迪帕克
一种可能的方法是使用 xsl:for-each-group
,并以 Employee
元素开始分组,其中日期不是前一天之后的一天(即它们是一个新组)
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))]">
我确定您是否有生成 EventId 的特定规则,但一种可能的方法如下
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
然后您将使用 current-group()
输出该特定组中具有相同 EventId 的所有行。试试这个 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:template match="Data">
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))]">
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
<xsl:for-each select="current-group()">
<xsl:value-of select="Employee_ID" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Time_type" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Date" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Hours" />
<xsl:text>,</xsl:text>
<xsl:value-of select="$EventId" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于你当前XML时,输出如下
EMP12345,Annual,2015-03-31,6,EMP12345-1
EMP12345,Sick,2015-04-01,6,EMP12345-2
EMP12345,Sick,2015-04-02,6,EMP12345-2
EMP12345,Sick,2015-04-03,6,EMP12345-2
EMP12345,Sick,2015-04-15,6,EMP12345-3
EMP12345,Sick,2015-04-16,6,EMP12345-3
EMP12346,Sick,2015-04-01,6,EMP12346-4
EMP12346,Sick,2015-04-02,6,EMP12346-4
请注意,这确实假定 Employee
元素按 Employee_id
、Date
和 time_type
顺序排序。
非常感谢@Tim 为我提供了解决方案。
我刚刚添加了一些标准来完全满足要求。
下面是更新后的 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:template match="Data">
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and ((xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))
or ((xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P3D')) and (format-date(xs:date(Date),'[F]')='Monday') and (format-date((xs:date(preceding-sibling::Employee[1]/Date)),'[F]')='Friday') ) ))]">
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
<xsl:for-each select="current-group()">
<xsl:value-of select="Employee_ID" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Time_type" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Date" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Hours" />
<xsl:text>,</xsl:text>
<xsl:value-of select="$EventId" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
希望你们 well.Thank 非常感谢你们 advance.Your 的帮助。
在为以下内容创建 XSLT (v2.0) 时遇到了麻烦requirement.Not 了解如何实现它。
要求: 根据每位员工的协商日期和时间类型生成唯一的事件 ID。
示例: 对于员工 EMP12345 正在休年假,日期为 2015-03-31,病假时间为 2015-04- 01 至 2015-04-03 和 2015-04-15 至 2015-04-16.
所以有2个连续日期的病假。所以需要生成两个唯一的事件id。
请参考以下预期输出。
XML
<?xml version='1.0' encoding='UTF-8'?>
<Data>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Annual</Time_type>
<Date>2015-03-31</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-01</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-02</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-03</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-15</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12345</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-16</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12346</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-01</Date>
<Hours>6</Hours>
</Employee>
<Employee>
<Employee_ID>EMP12346</Employee_ID>
<Time_type>Sick</Time_type>
<Date>2015-04-02</Date>
<Hours>6</Hours>
</Employee>
</Data>
预期输出:
Employee ID,Time Type,Date,Hours,Event ID
EMP12345,Annual,2015-03-31,6,
EMP12345,Sick,2015-04-01,6,12344EMP12345
EMP12345,Sick,2015-04-02,6,12344EMP12345
EMP12345,Sick,2015-04-03,6,12344EMP12345
EMP12345,Sick,2015-04-15,6,22344EMP12345
EMP12345,Sick,2015-04-16,6,22344EMP12345
EMP12346,Sick,2015-04-01,6,11111EMP12346
EMP12346,Sick,2015-04-02,6,11111EMP12346
谢谢,
迪帕克
一种可能的方法是使用 xsl:for-each-group
,并以 Employee
元素开始分组,其中日期不是前一天之后的一天(即它们是一个新组)
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))]">
我确定您是否有生成 EventId 的特定规则,但一种可能的方法如下
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
然后您将使用 current-group()
输出该特定组中具有相同 EventId 的所有行。试试这个 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:template match="Data">
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))]">
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
<xsl:for-each select="current-group()">
<xsl:value-of select="Employee_ID" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Time_type" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Date" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Hours" />
<xsl:text>,</xsl:text>
<xsl:value-of select="$EventId" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于你当前XML时,输出如下
EMP12345,Annual,2015-03-31,6,EMP12345-1
EMP12345,Sick,2015-04-01,6,EMP12345-2
EMP12345,Sick,2015-04-02,6,EMP12345-2
EMP12345,Sick,2015-04-03,6,EMP12345-2
EMP12345,Sick,2015-04-15,6,EMP12345-3
EMP12345,Sick,2015-04-16,6,EMP12345-3
EMP12346,Sick,2015-04-01,6,EMP12346-4
EMP12346,Sick,2015-04-02,6,EMP12346-4
请注意,这确实假定 Employee
元素按 Employee_id
、Date
和 time_type
顺序排序。
非常感谢@Tim 为我提供了解决方案。 我刚刚添加了一些标准来完全满足要求。
下面是更新后的 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:template match="Data">
<xsl:for-each-group select="Employee" group-starting-with="Employee[not(
Employee_ID = preceding-sibling::Employee[1]/Employee_ID
and Time_type = preceding-sibling::Employee[1]/Time_type
and ((xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P1D'))
or ((xs:date(Date) = xs:date(preceding-sibling::Employee[1]/Date) + xs:dayTimeDuration('P3D')) and (format-date(xs:date(Date),'[F]')='Monday') and (format-date((xs:date(preceding-sibling::Employee[1]/Date)),'[F]')='Friday') ) ))]">
<xsl:variable name="EventId" select="concat(Employee_ID, '-', position())" />
<xsl:for-each select="current-group()">
<xsl:value-of select="Employee_ID" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Time_type" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Date" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Hours" />
<xsl:text>,</xsl:text>
<xsl:value-of select="$EventId" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>