Disclaimer: I'm still learning XML / XSLT, so apologies if this is simple.
I'm trying to look up an element in node A, match it to a similar element in node B, and return an entry from node B to node A.
i.e. find the startDate under EmployeeTimeSheetEntry that matches EmployeeTimeValuationResult/bookingDate, and return the corresponding cust_Overtime_HR_Action element:
I'm trying to use a key to generate a lookup (based on the answer to this question: Print comma separated tokens when they have been looked up in another node), but I'm very unclear as to where to put the apply-templates statement to go and retrieve the node (and I'm very much confusing myself now, going round in circles).
Sample source XML:
<EmployeeTimeSheet>
<EmployeeTimeSheet>
<employeeTimeSheetEntry>
<EmployeeTimeSheetEntry>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
<startDate>2024-11-25T00:00:00.000</startDate>
</EmployeeTimeSheetEntry>
<EmployeeTimeSheetEntry>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
<startDate>2024-11-27T00:00:00.000</startDate>
</EmployeeTimeSheetEntry>
<EmployeeTimeSheetEntry>
<cust_Overtime_HR_ACTION>Payout</cust_Overtime_HR_ACTION>
<startDate>2024-11-30T00:00:00.000</startDate>
</EmployeeTimeSheetEntry>
</employeeTimeSheetEntry>
<employeeTimeValuationResult>
<EmployeeTimeValuationResult>
<bookingDate>2024-11-25T00:00:00.000</bookingDate>
</EmployeeTimeValuationResult>
</employeeTimeValuationResult>
</EmployeeTimeSheet>
And this is what I'm trying (and failing) to do in XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- generate lookup table - must be top level, i.e. before template match -->
<xsl:key name="timeSheetEntry" match="EmployeeTimeSheet/EmployeeTimeSheet/employeeTimeSheetEntry/EmployeeTimeSheetEntry" use="startDate"/>
<xsl:template match="/">
<EmployeeTimeSheet>
<!-- retrieve cust_Overtime_HR_ACTION where the bookingDate matches the startDate in above lookup -->
<xsl:template match="/">
<xsl:apply-templates select="key('timeSheetEntry', EmployeeTimeSheet/EmployeeTimeSheet/employeeTimeValuationResult/EmployeeTimeValuationResult/bookingDate)/cust_Overtime_HR_ACTION"/>
</xsl:template>
<xsl:for-each select="EmployeeTimeSheet/EmployeeTimeSheet">
<xsl:for-each select="employeeTimeValuationResult/EmployeeTimeValuationResult">
<xsl:variable name="var_TimeValResult" select="./*"></xsl:variable>
<EmployeeTimeSheet>
<xsl:copy-of select="$var_TimeValResult"/>
<xsl:template match="cust_Overtime_HR_ACTION">
<overtimeHRaction>
<xsl:value-of select="."/>
</overtimeHRaction>
</xsl:template>
</EmployeeTimeSheet>
</xsl:for-each>
</xsl:for-each> <!-- EmployeeTimeSheet/EmployeeTimeSheet -->
</EmployeeTimeSheet>
</xsl:template>
</xsl:stylesheet>
(apologies for beginner level code)
The output should look like this, with the element cust_Overtime_HR_ACTION for 2024-11-25 added to the EmployeeTimeValuationResult node:
<EmployeeTimeSheet>
<EmployeeTimeSheet>
<employeeTimeValuationResult>
<EmployeeTimeValuationResult>
<bookingDate>2024-11-25T00:00:00.000</bookingDate>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
</EmployeeTimeValuationResult>
</employeeTimeValuationResult>
</EmployeeTimeSheet>
Can anyone please advise where I'm going wrong? An XSLT test tool just says:
Unable to generate the XML document using the provided XML/XSL input. Errors were reported during stylesheet compilation
I can't figure out the logic required for the retrieval of the corresponding node.
Many thanks in advance for any guidance you can provide.
Kind regards, AJ
Consider this simplified example:
XML
<EmployeeTimeSheet>
<employeeTimeSheetEntry>
<EmployeeTimeSheetEntry>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
<startDate>2024-11-25T00:00:00.000</startDate>
</EmployeeTimeSheetEntry>
<EmployeeTimeSheetEntry>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
<startDate>2024-11-27T00:00:00.000</startDate>
</EmployeeTimeSheetEntry>
<EmployeeTimeSheetEntry>
<cust_Overtime_HR_ACTION>Payout</cust_Overtime_HR_ACTION>
<startDate>2024-11-30T00:00:00.000</startDate>
</EmployeeTimeSheetEntry>
</employeeTimeSheetEntry>
<employeeTimeValuationResult>
<EmployeeTimeValuationResult>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>9</hours>
<externalCode>ad0a255f256d44ddbe41bc6ab1d632b9</externalCode>
<entityUUID>6CB3BB8B01C4434FABD28A84554B6A88</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-25T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
</EmployeeTimeValuationResult>
<EmployeeTimeValuationResult>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>9</hours>
<externalCode>ee32afbee0e1452fbdcc21e9ee9e45e5</externalCode>
<entityUUID>397C8AED082B4B5192941FF6D02C29FA</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-26T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
</EmployeeTimeValuationResult>
<EmployeeTimeValuationResult>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>6.5</hours>
<externalCode>6d84652c40bb49c7b028fda128802100</externalCode>
<entityUUID>73F775BAF8EA43F3BE011EB0C34601E5</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-27T00:00:00.000</bookingDate>
<hoursAndMinutes>6:30</hoursAndMinutes>
</EmployeeTimeValuationResult>
<EmployeeTimeValuationResult>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>9</hours>
<externalCode>1527b80a2ccf4c409e9549bb22b0da20</externalCode>
<entityUUID>1397BD090FC0477C8C9EABE8B15939D2</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-28T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
</EmployeeTimeValuationResult>
<EmployeeTimeValuationResult>
<timeTypeGroup>TFX_ABSENCES_TTG</timeTypeGroup>
<hours>2.5</hours>
<externalCode>e2092ce1a0c6498fadc6d4caa0836ef1</externalCode>
<entityUUID>A996867E64B9422FBC1765662286B633</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-27T00:00:00.000</bookingDate>
<hoursAndMinutes>2:30</hoursAndMinutes>
</EmployeeTimeValuationResult>
<EmployeeTimeValuationResult>
<timeTypeGroup>TFX_ABSENCES_TTG</timeTypeGroup>
<hours>9</hours>
<externalCode>50745ba2f6c241fc925a666aef955a50</externalCode>
<entityUUID>65D732D727E346B79E60318C4703910C</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-29T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
</EmployeeTimeValuationResult>
</employeeTimeValuationResult>
</EmployeeTimeSheet>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="k1" match="EmployeeTimeSheetEntry" use="startDate" />
<xsl:template match="/EmployeeTimeSheet">
<results>
<xsl:for-each select="employeeTimeValuationResult/EmployeeTimeValuationResult">
<result>
<xsl:copy-of select="*"/>
<xsl:copy-of select="key('k1', bookingDate)/cust_Overtime_HR_ACTION"/>
</result>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<results>
<result>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>9</hours>
<externalCode>ad0a255f256d44ddbe41bc6ab1d632b9</externalCode>
<entityUUID>6CB3BB8B01C4434FABD28A84554B6A88</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-25T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
</result>
<result>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>9</hours>
<externalCode>ee32afbee0e1452fbdcc21e9ee9e45e5</externalCode>
<entityUUID>397C8AED082B4B5192941FF6D02C29FA</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-26T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
</result>
<result>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>6.5</hours>
<externalCode>6d84652c40bb49c7b028fda128802100</externalCode>
<entityUUID>73F775BAF8EA43F3BE011EB0C34601E5</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-27T00:00:00.000</bookingDate>
<hoursAndMinutes>6:30</hoursAndMinutes>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
</result>
<result>
<timeTypeGroup>SCHED_WORK_TIME_A</timeTypeGroup>
<hours>9</hours>
<externalCode>1527b80a2ccf4c409e9549bb22b0da20</externalCode>
<entityUUID>1397BD090FC0477C8C9EABE8B15939D2</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-28T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
</result>
<result>
<timeTypeGroup>TFX_ABSENCES_TTG</timeTypeGroup>
<hours>2.5</hours>
<externalCode>e2092ce1a0c6498fadc6d4caa0836ef1</externalCode>
<entityUUID>A996867E64B9422FBC1765662286B633</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-27T00:00:00.000</bookingDate>
<hoursAndMinutes>2:30</hoursAndMinutes>
<cust_Overtime_HR_ACTION>TOIL</cust_Overtime_HR_ACTION>
</result>
<result>
<timeTypeGroup>TFX_ABSENCES_TTG</timeTypeGroup>
<hours>9</hours>
<externalCode>50745ba2f6c241fc925a666aef955a50</externalCode>
<entityUUID>65D732D727E346B79E60318C4703910C</entityUUID>
<EmployeeTimeSheet_externalCode>dd70365f71084e63b1143d4c40bd40a9</EmployeeTimeSheet_externalCode>
<bookingDate>2024-11-29T00:00:00.000</bookingDate>
<hoursAndMinutes>9:00</hoursAndMinutes>
</result>
</results>