首页 > 解决方案 > 有没有办法编写 XSLT 转换以通过 emp、shift & swipeIn 和 Swipe Out 仅获取一条记录

问题描述

我需要为 Swipe punches 项目编写一个 XSLT 转换。目的是让员工、班次和日期只记录一条进出时间。

下面是我的 XML。我想编写 XSLT 以在一天内通过 Emp、Shift 和 Day 仅获得一次 Swipe In(应该是第一次 swipeIn)和一次 Swipe out(应该是最后一次 swipe Out)。

但是对于轮班:1C 更改刷卡日期,因为它是夜班。(夜班从下午 5 点(今天)开始到凌晨 4 点(明天)

我不确定这是否可能。

<?xml version="1.0" encoding="UTF-8"?>
<Data>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>08:53:54</Time>
        <Empid>100</Empid>
        <Gate>B-1a Main Door 2</Gate>
        <InOut>In</InOut>
        <Remark>Successful</Remark>
        <Shift>1A</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>10:53:54</Time>
        <Empid>100</Empid>
        <Gate>B-1a Main Door 3</Gate>
        <InOut>Out</InOut>
        <Remark>Successful</Remark>
        <Shift>1A</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>11:10:54</Time>
        <Empid>100</Empid>
        <Gate>B-1a Main Door 2</Gate>
        <InOut>In</InOut>
        <Remark>Successful</Remark>
        <Shift>1A</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>12:53:54</Time>
        <Empid>100</Empid>
        <Gate>B-1a Main Door 3</Gate>
        <InOut>Out</InOut>
        <Remark>Successful</Remark>
        <Shift>1A</Shift>
    </Employees>
        <Employees>
        <Date>2019-12-16</Date>
        <Time>14:00:54</Time>
        <Empid>100</Empid>
        <Gate>B-1a Main Door 2</Gate>
        <InOut>In</InOut>
        <Remark>Successful</Remark>
        <Shift>1A</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>18:00:54</Time>
        <Empid>100</Empid>
        <Gate>B-1a Main Door 3</Gate>
        <InOut>Out</InOut>
        <Remark>Successful</Remark>
        <Shift>1A</Shift>
    </Employees>    
     <Employees>
        <Date>2019-12-16</Date>
        <Time>17:30:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 2</Gate>
        <InOut>In</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>19:00:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 3</Gate>
        <InOut>Out</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>20:10:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 2</Gate>
        <InOut>In</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-16</Date>
        <Time>23:53:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 3</Gate>
        <InOut>Out</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
        <Employees>
        <Date>2019-12-17</Date>
        <Time>01:30:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 2</Gate>
        <InOut>In</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-17</Date>
        <Time>03:00:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 3</Gate>
        <InOut>Out</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
        </Employees>
        <Employees>
        <Date>2019-12-17</Date>
        <Time>03:30:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 2</Gate>
        <InOut>In</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
    <Employees>
        <Date>2019-12-17</Date>
        <Time>04:00:54</Time>
        <Empid>101</Empid>
        <Gate>B-1a Main Door 3</Gate>
        <InOut>Out</InOut>
        <Remark>Successful</Remark>
        <Shift>1C</Shift>
    </Employees>
</Data>

输出应该是这样的:

在此处输入图像描述

标签: xmlxsltxslt-2.0xslt-3.0

解决方案


主要方法是对三个关键值进行简单的复合分组,只有夜班会使事情复杂化,因为您必须对两个不同的日期进行分组,并且还必须更改表达式以查找时间:

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

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

  <xsl:output method="html" indent="yes" html-version="5"/>

  <xsl:template match="Data">
      <table>
          <thead>
              <tr>
                  <th>Date</th>
                  <th>In-Time</th>
                  <th>Out-Time</th>
                  <th>EmpId</th>
                  <th>Shift</th>
              </tr>
          </thead>
          <xsl:for-each-group select="Employees" composite="yes" 
              group-by="Empid, 
                        if (Shift != '1C') 
                        then 
                          xs:date(Date) 
                        else if (xs:time(Time) lt xs:time('08:00:00'))
                        then 
                          xs:date(Date) - xs:dayTimeDuration('P1D')
                        else 
                          xs:date(Date), 
                        Shift">
              <tbody>
                  <tr>
                      <td>{current-grouping-key()[2]}</td>
                      <td>{if (Shift != '1C')
                           then min(current-group()[InOut = 'In']/xs:time(Time))
                           else
                             min(current-group()[xs:date(Date) = current-grouping-key()[2]][InOut = 'In']/xs:time(Time))
                          }</td>
                      <td>{if (Shift != '1C')
                           then 
                             max(current-group()[InOut = 'Out']/xs:time(Time))
                           else 
                             max(current-group()[xs:date(Date) > current-grouping-key()[2]][InOut = 'Out']/xs:time(Time))}</td>
                      <td>{current-grouping-key()[1]}</td>
                      <td>{current-grouping-key()[3]}</td>
                  </tr>
              </tbody>
          </xsl:for-each-group>
      </table>
  </xsl:template>
  <xsl:template match="/">
    <html>
      <head>
        <title>.NET XSLT Fiddle Example</title>
      </head>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>

  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bFWRAp4

这是假设夜班总是在第二天结束,如果有人因病在午夜前辍学,我不确定这是否现实。

我没有尝试格式化日期或时间,使用format-dateXSLT/XPath 提供的各种时间函数。


推荐阅读