在使用 XSLT 分组和转置数据方面需要帮助
Need help in grouping and transposing data using XSLT
我在条件分组和转置 XML 数据方面需要帮助。
- 我需要使用月份中的星期几、工作人员 ID 和 Rate_Category_Code 对数据进行分组和转置。需要在适当的周内报告 Hours_Worked。其他一周的时间都是空白的。 XML 中的数据永远不会超过一个月。
- 如果报告了加班时间(由 Rate_Category_Code 标识为加班),那么我需要为报告加班时间的那一周创建单独的行。
下面是 XML 数据 -
``
<?xml version="1.0" encoding="UTF-8"?>
<wd:Report_Data xmlns:wd="urn:com.workday.report/INT1120_CR_HR_Fieldglass_Daily_Timesheet">
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001743</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>ST</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>8</wd:Hours_Worked>
<wd:Reported_Date>2019-06-10</wd:Reported_Date>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001743</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>ST</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>8</wd:Hours_Worked>
<wd:Reported_Date>2019-06-18</wd:Reported_Date>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001743</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>OT</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>1</wd:Hours_Worked>
<wd:Reported_Date>2019-06-10</wd:Reported_Date>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001742</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>ST</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>9</wd:Hours_Worked>
<wd:Reported_Date>2019-06-20</wd:Reported_Date>
</wd:Report_Entry>
</wd:Report_Data>
``
期望的输出 -
``
Type=Upload Full Time Sheet with Revision
Transaction=True
Approval Required=True
Messaging Required=False
Language=English (United States)
Number Format=#,##9.99 (Example: 1,234,567.99)
Date Format=MM/DD/YYYY
Submit=FALSE
Buyer=FNRA
Supplier Review=False
Comments=
Worker_ID|Month_Start_Date|First_Monday|Cost_Center_Code|Task_Code|GL_Account_Code|Rate_Category_Code|UOM|Mon_Hrs|Tue_Hrs|Wed_Hrs|Thu_Hrs|Fri_Hrs|Sat_Hrs|Sun_Hrs
FNRAWK00001743|06/01/2019|05/27/2019||01|Default|ST|HR||||||||
FNRAWK00001743|06/01/2019|06/03/2019||01|Default|ST|HR||||||||
FNRAWK00001743|06/01/2019|06/10/2019||01|Default|ST|HR|8|||||||
FNRAWK00001743|06/01/2019|06/10/2019||01|Default|OT|HR|1|||||||
FNRAWK00001743|06/01/2019|06/17/2019||01|Default|ST|HR||8||||||
FNRAWK00001743|06/01/2019|06/24/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|05/27/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|06/03/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|06/10/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|06/10/2019||01|Default|OT|HR||||||||
FNRAWK00001742|06/01/2019|06/17/2019||01|Default|ST|HR||||9||||
FNRAWK00001742|06/01/2019|06/24/2019||01|Default|ST|HR||||||||
``
XSLT -
``
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wd="urn:com.workday.report/INT1120_CR_HR_Fieldglass_Daily_Timesheet" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:my="http://www.example.com/my" xmlns:functx="http://www.functx.com" exclude-result-prefixes="xs my functx">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:variable name="Linefeed" select="' '"/>
<xsl:variable name="Delimiter" select=" '|' "/>
<xsl:function name="functx:repeat-string" as="xs:string">
<xsl:param name="stringToRepeat" as="xs:string?"/>
<xsl:param name="count" as="xs:integer"/>
<xsl:sequence select="string-join((for $i in 1 to $count return $stringToRepeat),'')"/>
</xsl:function>
<xsl:function name="functx:pad-integer-to-length" as="xs:string">
<xsl:param name="integerToPad" as="xs:anyAtomicType?"/>
<xsl:param name="length" as="xs:integer"/>
<xsl:sequence select="if ($length < string-length(string($integerToPad))) then error(xs:QName('functx:Integer_Longer_Than_Length')) else concat (functx:repeat-string('0',$length - string-length(string($integerToPad))),string($integerToPad))"/>
</xsl:function>
<xsl:function name="functx:date" as="xs:date">
<xsl:param name="year" as="xs:anyAtomicType"/>
<xsl:param name="month" as="xs:anyAtomicType"/>
<xsl:param name="day" as="xs:anyAtomicType"/>
<xsl:sequence select="xs:date(concat(functx:pad-integer-to-length(xs:integer($year),4),'-',functx:pad-integer-to-length(xs:integer($month),2),'-',functx:pad-integer-to-length(xs:integer($day),2)))"/>
</xsl:function>
<!--Function which accepts date as input and returns the date for first day of the month (Input Date)-->
<xsl:function name="functx:first-day-of-month" as="xs:date?">
<xsl:param name="date" as="xs:anyAtomicType?"/>
<xsl:sequence select="functx:date(year-from-date(xs:date($date)),month-from-date(xs:date($date)),1)"/>
</xsl:function>
<!--Function which accepts date as input and returns the date for first day of the week-->
<xsl:function name="my:thisMonday">
<xsl:param name="date"/>
<xsl:variable name="epoch" select="xs:date('0001-01-01')"/>
<xsl:variable name="dayNumber" select="fn:days-from-duration($date - $epoch)"/>
<xsl:variable name="dayOfWeek" select="$dayNumber mod 7"/>
<xsl:value-of select="$date - xs:dayTimeDuration(concat('P', $dayOfWeek, 'D' ))"/>
</xsl:function>
<xsl:template match="wd:Report_Data">
<File>
<Header>
<xsl:text>Type=Upload Full Time Sheet with Revision</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Transaction=True</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Approval Required=True</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Messaging Required=False</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Language=English (United States)</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Number Format=#,##9.99 (Example: 1,234,567.99)</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Date Format=MM/DD/YYYY</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Submit=FALSE</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Buyer=FNRA</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Supplier Review=False</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Comments=</xsl:text>
<xsl:value-of select="$Linefeed"/>
</Header>
<xsl:value-of select="$Linefeed"/>
<Header>
<xsl:text>Worker_ID|Date|Week_Start_Date|Cost_Center_Code|Task_Code|GL_Account_Code|Rate_Category_Code|UOM|Mon_Hrs|Tue_Hrs|Wed_Hrs|Thu_Hrs|Fri_Hrs|Sat_Hrs|Sun_Hrs</xsl:text>
<xsl:value-of select="$Linefeed"/>
</Header>
<xsl:for-each select="wd:Report_Entry">
<xsl:call-template name="Write_Rows"/>
</xsl:for-each>
</File>
</xsl:template>
<xsl:template name="Write_Rows">
<Record>
<Worker_ID>
<xsl:value-of select="wd:Worker_ID"/>
</Worker_ID>
<xsl:value-of select="$Delimiter"/>
<Date>
<!--<xsl:value-of select="concat(substring(wd:Date,6, 2),'/',substring(wd:Date, 9, 2),'/',substring(wd:Date, 1, 4))"/>-->
<!--Pass date in YYYY-MM-DD format to custom function and format the return value to 'MM/DD/YYYY'-->
<xsl:variable name="StartDateOfMonth" select="string(functx:first-day-of-month(xs:date(concat(substring(wd:Reported_Date, 1, 4),'-', substring(wd:Reported_Date,6, 2),'-',substring(wd:Reported_Date, 9, 2)))))"/>
<xsl:value-of select="concat(substring($StartDateOfMonth,6,2),'/',substring($StartDateOfMonth,9,2),'/',substring($StartDateOfMonth,1,4))"/>
</Date>
<xsl:value-of select="$Delimiter"/>
<Week_Start_Date>
<!--<xsl:variable name="WeekStartDate" select="my:thisMonday(xs:date('2019-06-01'))"/>-->
<!--Format the return value to 'MM/DD/YYYY'-->
<xsl:variable name="WeekStartDate" select="my:thisMonday(xs:date(wd:Reported_Date))"/>
<xsl:value-of select="concat(substring($WeekStartDate,6,2),'/',substring($WeekStartDate,9,2),'/',substring($WeekStartDate,1,4))"/>
</Week_Start_Date>
<xsl:value-of select="$Delimiter"/>
<Cost_Center_Code>
<xsl:value-of select="wd:Cost_Center_Code"/>
</Cost_Center_Code>
<xsl:value-of select="$Delimiter"/>
<Task_Code>
<xsl:value-of select="wd:Task_Code"/>
</Task_Code>
<xsl:value-of select="$Delimiter"/>
<GL_Account_Code>
<xsl:value-of select="wd:GL_Account_Code"/>
</GL_Account_Code>
<xsl:value-of select="$Delimiter"/>
<Rate_Category_Code>
<xsl:value-of select="wd:Rate_Category_Code"/>
</Rate_Category_Code>
<xsl:value-of select="$Delimiter"/>
<UOM>
<xsl:value-of select="wd:UOM"/>
</UOM>
<xsl:value-of select="$Delimiter"/>
<Hours_Worked>
<xsl:value-of select="wd:Hours_Worked"/>
</Hours_Worked>
<xsl:value-of select="$Delimiter"/>
<Overtime>
<xsl:value-of select="wd:Overtime"/>
</Overtime>
<xsl:value-of select="$Linefeed"/>
</Record>
</xsl:template>
</xsl:stylesheet>
``
我认为部分任务是使用复合键进行分组,例如在 XSLT 3 中:
<xsl:for-each-group select="wd:Report_Entry" composite="yes" group-by="wd:Worker_ID, wd:Rate_Category_Code, my:thisMonday(xs:date(wd:Reported_Date))">
<xsl:value-of select="current-grouping-key(), sum(current-group()/wd:Hours_Worked)" separator="|"/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
即给出现有数据:
FNRAWK00001743|ST|2019-06-10|8
FNRAWK00001743|ST|2019-06-17|8
FNRAWK00001743|OT|2019-06-10|1
FNRAWK00001742|ST|2019-06-17|9
您将需要添加逻辑以输出没有数据的周的空行。
我在条件分组和转置 XML 数据方面需要帮助。
- 我需要使用月份中的星期几、工作人员 ID 和 Rate_Category_Code 对数据进行分组和转置。需要在适当的周内报告 Hours_Worked。其他一周的时间都是空白的。 XML 中的数据永远不会超过一个月。
- 如果报告了加班时间(由 Rate_Category_Code 标识为加班),那么我需要为报告加班时间的那一周创建单独的行。
下面是 XML 数据 -
``
<?xml version="1.0" encoding="UTF-8"?>
<wd:Report_Data xmlns:wd="urn:com.workday.report/INT1120_CR_HR_Fieldglass_Daily_Timesheet">
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001743</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>ST</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>8</wd:Hours_Worked>
<wd:Reported_Date>2019-06-10</wd:Reported_Date>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001743</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>ST</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>8</wd:Hours_Worked>
<wd:Reported_Date>2019-06-18</wd:Reported_Date>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001743</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>OT</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>1</wd:Hours_Worked>
<wd:Reported_Date>2019-06-10</wd:Reported_Date>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker_ID>FNRAWK00001742</wd:Worker_ID>
<wd:Task_Code>01</wd:Task_Code>
<wd:GL_Account_Code>Default</wd:GL_Account_Code>
<wd:Rate_Category_Code>ST</wd:Rate_Category_Code>
<wd:UOM>HR</wd:UOM>
<wd:Hours_Worked>9</wd:Hours_Worked>
<wd:Reported_Date>2019-06-20</wd:Reported_Date>
</wd:Report_Entry>
</wd:Report_Data>
``
期望的输出 -
``
Type=Upload Full Time Sheet with Revision
Transaction=True
Approval Required=True
Messaging Required=False
Language=English (United States)
Number Format=#,##9.99 (Example: 1,234,567.99)
Date Format=MM/DD/YYYY
Submit=FALSE
Buyer=FNRA
Supplier Review=False
Comments=
Worker_ID|Month_Start_Date|First_Monday|Cost_Center_Code|Task_Code|GL_Account_Code|Rate_Category_Code|UOM|Mon_Hrs|Tue_Hrs|Wed_Hrs|Thu_Hrs|Fri_Hrs|Sat_Hrs|Sun_Hrs
FNRAWK00001743|06/01/2019|05/27/2019||01|Default|ST|HR||||||||
FNRAWK00001743|06/01/2019|06/03/2019||01|Default|ST|HR||||||||
FNRAWK00001743|06/01/2019|06/10/2019||01|Default|ST|HR|8|||||||
FNRAWK00001743|06/01/2019|06/10/2019||01|Default|OT|HR|1|||||||
FNRAWK00001743|06/01/2019|06/17/2019||01|Default|ST|HR||8||||||
FNRAWK00001743|06/01/2019|06/24/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|05/27/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|06/03/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|06/10/2019||01|Default|ST|HR||||||||
FNRAWK00001742|06/01/2019|06/10/2019||01|Default|OT|HR||||||||
FNRAWK00001742|06/01/2019|06/17/2019||01|Default|ST|HR||||9||||
FNRAWK00001742|06/01/2019|06/24/2019||01|Default|ST|HR||||||||
``
XSLT -
``
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wd="urn:com.workday.report/INT1120_CR_HR_Fieldglass_Daily_Timesheet" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:my="http://www.example.com/my" xmlns:functx="http://www.functx.com" exclude-result-prefixes="xs my functx">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:variable name="Linefeed" select="' '"/>
<xsl:variable name="Delimiter" select=" '|' "/>
<xsl:function name="functx:repeat-string" as="xs:string">
<xsl:param name="stringToRepeat" as="xs:string?"/>
<xsl:param name="count" as="xs:integer"/>
<xsl:sequence select="string-join((for $i in 1 to $count return $stringToRepeat),'')"/>
</xsl:function>
<xsl:function name="functx:pad-integer-to-length" as="xs:string">
<xsl:param name="integerToPad" as="xs:anyAtomicType?"/>
<xsl:param name="length" as="xs:integer"/>
<xsl:sequence select="if ($length < string-length(string($integerToPad))) then error(xs:QName('functx:Integer_Longer_Than_Length')) else concat (functx:repeat-string('0',$length - string-length(string($integerToPad))),string($integerToPad))"/>
</xsl:function>
<xsl:function name="functx:date" as="xs:date">
<xsl:param name="year" as="xs:anyAtomicType"/>
<xsl:param name="month" as="xs:anyAtomicType"/>
<xsl:param name="day" as="xs:anyAtomicType"/>
<xsl:sequence select="xs:date(concat(functx:pad-integer-to-length(xs:integer($year),4),'-',functx:pad-integer-to-length(xs:integer($month),2),'-',functx:pad-integer-to-length(xs:integer($day),2)))"/>
</xsl:function>
<!--Function which accepts date as input and returns the date for first day of the month (Input Date)-->
<xsl:function name="functx:first-day-of-month" as="xs:date?">
<xsl:param name="date" as="xs:anyAtomicType?"/>
<xsl:sequence select="functx:date(year-from-date(xs:date($date)),month-from-date(xs:date($date)),1)"/>
</xsl:function>
<!--Function which accepts date as input and returns the date for first day of the week-->
<xsl:function name="my:thisMonday">
<xsl:param name="date"/>
<xsl:variable name="epoch" select="xs:date('0001-01-01')"/>
<xsl:variable name="dayNumber" select="fn:days-from-duration($date - $epoch)"/>
<xsl:variable name="dayOfWeek" select="$dayNumber mod 7"/>
<xsl:value-of select="$date - xs:dayTimeDuration(concat('P', $dayOfWeek, 'D' ))"/>
</xsl:function>
<xsl:template match="wd:Report_Data">
<File>
<Header>
<xsl:text>Type=Upload Full Time Sheet with Revision</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Transaction=True</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Approval Required=True</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Messaging Required=False</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Language=English (United States)</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Number Format=#,##9.99 (Example: 1,234,567.99)</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Date Format=MM/DD/YYYY</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Submit=FALSE</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Buyer=FNRA</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Supplier Review=False</xsl:text>
<xsl:value-of select="$Linefeed"/>
<xsl:text>Comments=</xsl:text>
<xsl:value-of select="$Linefeed"/>
</Header>
<xsl:value-of select="$Linefeed"/>
<Header>
<xsl:text>Worker_ID|Date|Week_Start_Date|Cost_Center_Code|Task_Code|GL_Account_Code|Rate_Category_Code|UOM|Mon_Hrs|Tue_Hrs|Wed_Hrs|Thu_Hrs|Fri_Hrs|Sat_Hrs|Sun_Hrs</xsl:text>
<xsl:value-of select="$Linefeed"/>
</Header>
<xsl:for-each select="wd:Report_Entry">
<xsl:call-template name="Write_Rows"/>
</xsl:for-each>
</File>
</xsl:template>
<xsl:template name="Write_Rows">
<Record>
<Worker_ID>
<xsl:value-of select="wd:Worker_ID"/>
</Worker_ID>
<xsl:value-of select="$Delimiter"/>
<Date>
<!--<xsl:value-of select="concat(substring(wd:Date,6, 2),'/',substring(wd:Date, 9, 2),'/',substring(wd:Date, 1, 4))"/>-->
<!--Pass date in YYYY-MM-DD format to custom function and format the return value to 'MM/DD/YYYY'-->
<xsl:variable name="StartDateOfMonth" select="string(functx:first-day-of-month(xs:date(concat(substring(wd:Reported_Date, 1, 4),'-', substring(wd:Reported_Date,6, 2),'-',substring(wd:Reported_Date, 9, 2)))))"/>
<xsl:value-of select="concat(substring($StartDateOfMonth,6,2),'/',substring($StartDateOfMonth,9,2),'/',substring($StartDateOfMonth,1,4))"/>
</Date>
<xsl:value-of select="$Delimiter"/>
<Week_Start_Date>
<!--<xsl:variable name="WeekStartDate" select="my:thisMonday(xs:date('2019-06-01'))"/>-->
<!--Format the return value to 'MM/DD/YYYY'-->
<xsl:variable name="WeekStartDate" select="my:thisMonday(xs:date(wd:Reported_Date))"/>
<xsl:value-of select="concat(substring($WeekStartDate,6,2),'/',substring($WeekStartDate,9,2),'/',substring($WeekStartDate,1,4))"/>
</Week_Start_Date>
<xsl:value-of select="$Delimiter"/>
<Cost_Center_Code>
<xsl:value-of select="wd:Cost_Center_Code"/>
</Cost_Center_Code>
<xsl:value-of select="$Delimiter"/>
<Task_Code>
<xsl:value-of select="wd:Task_Code"/>
</Task_Code>
<xsl:value-of select="$Delimiter"/>
<GL_Account_Code>
<xsl:value-of select="wd:GL_Account_Code"/>
</GL_Account_Code>
<xsl:value-of select="$Delimiter"/>
<Rate_Category_Code>
<xsl:value-of select="wd:Rate_Category_Code"/>
</Rate_Category_Code>
<xsl:value-of select="$Delimiter"/>
<UOM>
<xsl:value-of select="wd:UOM"/>
</UOM>
<xsl:value-of select="$Delimiter"/>
<Hours_Worked>
<xsl:value-of select="wd:Hours_Worked"/>
</Hours_Worked>
<xsl:value-of select="$Delimiter"/>
<Overtime>
<xsl:value-of select="wd:Overtime"/>
</Overtime>
<xsl:value-of select="$Linefeed"/>
</Record>
</xsl:template>
</xsl:stylesheet>
``
我认为部分任务是使用复合键进行分组,例如在 XSLT 3 中:
<xsl:for-each-group select="wd:Report_Entry" composite="yes" group-by="wd:Worker_ID, wd:Rate_Category_Code, my:thisMonday(xs:date(wd:Reported_Date))">
<xsl:value-of select="current-grouping-key(), sum(current-group()/wd:Hours_Worked)" separator="|"/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
即给出现有数据:
FNRAWK00001743|ST|2019-06-10|8
FNRAWK00001743|ST|2019-06-17|8
FNRAWK00001743|OT|2019-06-10|1
FNRAWK00001742|ST|2019-06-17|9
您将需要添加逻辑以输出没有数据的周的空行。