Я пытаюсь создать файл .csv, используя XSLT 1.0, где я хочу иметь возможность группировать как по идентификатору, так и по дате.
У меня есть следующий XML:
<?xml version="1.0" encoding="UTF-8"?><RunPeriod PeriodStart="01102019" PeriodEnd="02102019"><Employees>
<ID WageCode="2250"><Name>John Doe</Name><Date>01-10-2019</Date><Starttime>08:30</Starttime><Endtime>12:00</Endtime><Absence></Absence><PublicHoliday>0</PublicHoliday><OvertimeStart>08:30</OvertimeStart><OvertimeEnd>12:00</OvertimeEnd></ID>
<DatesAndWeekdays><Dates>01-10-2019</Dates><NameOfWeekday>Tuesday</NameOfWeekday></DatesAndWeekdays>
<ID WageCode="1857"><Name>Jane Doe</Name><Date>01-10-2019</Date><Starttime>09:45</Starttime><Endtime>12:45</Endtime><Absence></Absence><PublicHoliday>0</PublicHoliday><OvertimeStart>09:45</OvertimeStart><OvertimeEnd>12:45</OvertimeEnd></ID>
<DatesAndWeekdays><Dates>01-10-2019</Dates><NameOfWeekday>Tuesday</NameOfWeekday></DatesAndWeekdays>
<ID WageCode="2250"><Name>John Doe</Name><Date>01-10-2019</Date><Starttime>13:15</Starttime><Endtime>16:00</Endtime><Absence></Absence><PublicHoliday>0</PublicHoliday><OvertimeStart>13:15</OvertimeStart><OvertimeEnd>16:00</OvertimeEnd></ID>
<DatesAndWeekdays><Dates>01-10-2019</Dates><NameOfWeekday>Tuesday</NameOfWeekday></DatesAndWeekdays>
<ID WageCode="1857"><Name>Jane Doe</Name><Date>01-10-2019</Date><Starttime>14:45</Starttime><Endtime>17:30</Endtime><Absence></Absence><PublicHoliday>0</PublicHoliday><OvertimeStart>14:45</OvertimeStart><OvertimeEnd>17:30</OvertimeEnd></ID>
<DatesAndWeekdays><Dates>01-10-2019</Dates><NameOfWeekday>Tuesday</NameOfWeekday></DatesAndWeekdays>
<ID WageCode="2250"><Name>John Doe</Name><Date>01-10-2019</Date><Starttime>17:30</Starttime><Endtime>20:30</Endtime><Absence></Absence><PublicHoliday>0</PublicHoliday><OvertimeStart>17:30</OvertimeStart><OvertimeEnd>20:30</OvertimeEnd></ID>
<DatesAndWeekdays><Dates>01-10-2019</Dates><NameOfWeekday>Tuesday</NameOfWeekday></DatesAndWeekdays>
<ID WageCode="2250"><Name>John Doe</Name><Date>02-10-2019</Date><Starttime>08:15</Starttime><Endtime>18:00</Endtime><Absence></Absence><PublicHoliday>0</PublicHoliday><OvertimeStart>08:15</OvertimeStart><OvertimeEnd>18:00</OvertimeEnd></ID>
<DatesAndWeekdays><Dates>02-10-2019</Dates><NameOfWeekday>Wednesday</NameOfWeekday></DatesAndWeekdays>
<ID WageCode="1857"><Name>Jane Doe</Name><Date>02-10-2019</Date><Starttime>08:45</Starttime><Endtime>17:30</Endtime><Absence></Absence><PublicHoliday>0</PublicHoliday><OvertimeStart>08:45</OvertimeStart><OvertimeEnd>17:30</OvertimeEnd></ID>
<DatesAndWeekdays><Dates>02-10-2019</Dates><NameOfWeekday>Wednesday</NameOfWeekday></DatesAndWeekdays>
</Employees></RunPeriod>
Где мои два предмета работают по вторникам и средам.До сих пор я был в состоянии сгруппировать их по их идентификатору, поэтому я получаю по одной строке на один день, используя следующий код:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:key name="grpEmployee" match="ID" use="@WageCode"/>
<xsl:key name="grpDay" match="DatesAndWeekdays" use="Dates"/>
<xsl:variable name="startDate" select="RunPeriod/@PeriodStart"/>
<xsl:variable name="endDate" select="RunPeriod/@PeriodEnd"/>
<xsl:template match="Employees">
<xsl:text>Employee name</xsl:text> <!--> Add first column employee name -->
<xsl:text>;</xsl:text>
<!--> Add the dates from the export period - PeriodStart and PeriodEnd -->
<xsl:call-template name="DateList">
<xsl:with-param name="day" select="number(substring($startDate, 1, 2))" />
<xsl:with-param name="month" select="number(substring($startDate, 3, 2))" />
<xsl:with-param name="year" select="number(substring($startDate, 5))" />
</xsl:call-template>
<xsl:text>
</xsl:text>
<!--> Add employee data-->
<xsl:apply-templates select="ID[generate-id(.)=generate-id(key('grpEmployee',@WageCode)[1])]"/>
</xsl:template>
<xsl:template match="ID">
<xsl:value-of select="Name"/>
<xsl:text>;</xsl:text>
<xsl:for-each select="key('grpEmployee', @WageCode)">
<xsl:choose>
<xsl:when test="Absence = 'Annual leave'">
<xsl:value-of select="Absence"/>
</xsl:when>
<xsl:when test="PublicHoliday = '1'">
<xsl:text>Public Holiday</xsl:text>
</xsl:when>
<xsl:when test="Starttime = '00:00' and Endtime = '00:00'">
<xsl:text>Day off</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="Starttime"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="Endtime"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text>;</xsl:text>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="DateList">
<xsl:param name="day" select="1" />
<xsl:param name="month" select="1" />
<xsl:param name="year" select="1" />
<xsl:variable name="validationResult">
<xsl:call-template name="date-is-valid">
<xsl:with-param name="day" select="$day"/>
<xsl:with-param name="month" select="$month"/>
<xsl:with-param name="year" select="$year"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$validationResult = 0">
<xsl:choose>
<xsl:when test="$month > 12">
<xsl:call-template name="DateList">
<xsl:with-param name="day" select="1" />
<xsl:with-param name="month" select="1" />
<xsl:with-param name="year" select="$year + 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="DateList">
<xsl:with-param name="day" select="1" />
<xsl:with-param name="month" select="$month + 1" />
<xsl:with-param name="year" select="$year" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="currentDate" select="concat(format-number($day, '00'), format-number($month, '00'), $year)" />
<xsl:value-of select="concat($day,'-',$month,'-',$year)" />
<xsl:text>;</xsl:text>
<xsl:if test="not($currentDate = $endDate)">
<xsl:call-template name="DateList">
<xsl:with-param name="day" select="$day + 1" />
<xsl:with-param name="month" select="$month" />
<xsl:with-param name="year" select="$year" />
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="date-is-valid">
<xsl:param name="year" select="''"/>
<xsl:param name="month" select="''"/>
<xsl:param name="day" select="''"/>
<xsl:variable name="year-is-integer" select="number($year) = $year and floor($year) = $year" />
<xsl:variable name="month-is-integer" select="number($month) = $month and floor($month) = $month" />
<xsl:variable name="day-is-integer" select="number($day) = $day and floor($day) = $day" />
<xsl:choose>
<xsl:when test="
not($year-is-integer) or not($month-is-integer) or not($day-is-integer) or
$month < 1 or $month > 12 or
$day < 1 or $day > 31 or (
($year mod 4 = 0 and $month = 2 and $day > 29) or
($year mod 4 != 0 and $month = 2 and $day > 28) or
(($month = 4 or $month = 6 or $month = 9 or $month = 11) and $day > 30))">
<xsl:value-of select="0"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:transform>
ожидаемый результат:
Employee name Tuesday Wednesday
01-10-2019 02-10-2019
John Doe 08:30-12:00 13:15-16:00 17:30-20:00 08:15-18:00
Jane Doe 09:45-12:45 14:45-17:30 08:45-17:30
фактическийВывод:
Employee name Tuesday Wednesday
01-10-2019 02-10-2019
John Doe 08:30-12:00 13:15-16:00 17:30-20:30 08:15-18:00
Jane Doe 09:45-12:45 14:45-17:30 08:45-17:30
Если у моих предметов есть несколько рабочих дней в день, я хочу, чтобы все рабочие часы были показаны в этот день.Код работает нормально, если у них есть только одно рабочее время, например, 08: 15-18: 00, но он не может обрабатывать несколько рабочих дней в день.
Как мне настроить рабочее время в соответствии с их соответствующей датой?