Есть ли способ написать XSLT-преобразование, чтобы получить только одну запись по emp, shift & swipeIn и Swipe Out - PullRequest
0 голосов
/ 31 января 2020

Мне нужно написать XSLT-преобразование для проекта Swipe штампов. Намерение состоит в том, чтобы получить только одну запись времени входа и выхода по сотруднику, смене и дню.

Ниже мой XML. Я хочу написать XSLT, чтобы получить только один Swipe In (который должен быть первым swipeIn) и один Swipe Out (который должен быть последним Swipe In) в день по Emp, Shift и Day.

Но для смены: 1 C Измените дату смахивания, поскольку это ночная смена. (ночная смена начинается с 17:00 (сегодня) до 4:00 (завтра)

Я не уверен, возможно ли это или нет.

<?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>

Вывод должен быть таким:

enter image description here

1 Ответ

0 голосов
/ 31 января 2020

Основной подход - простая составная группировка по трем ключевым значениям, только ночная смена усложняет ситуацию, так как вам нужно сгруппировать две разные даты, а также изменить выражения, чтобы найти время:

<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

Предполагается, что ночная смена всегда прекращается на следующий день, я не уверен, что это реально c, если кто-то выпадет до полуночи из-за болезни.

Я не пытался форматировать даты или время, использую различные format-date и функции времени, предлагаемые XSLT / XPath.

...