Created
July 13, 2026 10:26
-
-
Save r4hulp/9b41c01cd4a5a321326261a1b9b3b1da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?xml version="1.0" encoding="UTF-8"?> | |
| <xsl:stylesheet version="1.0" | |
| xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
| xmlns:ws="urn:com.workday/workersync" | |
| xmlns:xtt="urn:com.workday/xtt" | |
| exclude-result-prefixes="ws"> | |
| <!-- | |
| Important: | |
| The XSLT must first output valid XML. | |
| Workday XTT then converts that XML into CSV text. | |
| --> | |
| <xsl:output method="xml" | |
| encoding="UTF-8" | |
| omit-xml-declaration="no" | |
| indent="yes"/> | |
| <xsl:template match="/"> | |
| <File> | |
| <!-- ================================================= | |
| CSV header | |
| XTT places commas between the child elements. | |
| ================================================= --> | |
| <Header xtt:separator=","> | |
| <Employee_ID>Employee_ID</Employee_ID> | |
| <Legal_First_Name>Legal_First_Name</Legal_First_Name> | |
| <Legal_Last_Name>Legal_Last_Name</Legal_Last_Name> | |
| <Location_Country>Location_Country</Location_Country> | |
| <Language>Language</Language> | |
| <Work_Email>Work_Email</Work_Email> | |
| <Home_Email>Home_Email</Home_Email> | |
| <Job_Profile>Job_Profile</Job_Profile> | |
| <Hire_Date>Hire_Date</Hire_Date> | |
| <Termination_Date>Termination_Date</Termination_Date> | |
| <Active>Active</Active> | |
| <Worker_Type>Worker_Type</Worker_Type> | |
| </Header> | |
| <!-- ================================================= | |
| One Record element becomes one CSV row. | |
| ================================================= --> | |
| <xsl:for-each select="ws:Worker_Sync/ws:Worker"> | |
| <Record xtt:separator=","> | |
| <!-- Employee ID --> | |
| <Employee_ID> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" | |
| select="normalize-space(ws:Summary/ws:Employee_ID)"/> | |
| </xsl:call-template> | |
| </Employee_ID> | |
| <!-- Legal first name --> | |
| <Legal_First_Name> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" | |
| select="normalize-space(ws:Personal/ws:Name_Data/ws:First_Name)"/> | |
| </xsl:call-template> | |
| </Legal_First_Name> | |
| <!-- Legal last name --> | |
| <Legal_Last_Name> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" | |
| select="normalize-space(ws:Personal/ws:Name_Data/ws:Last_Name)"/> | |
| </xsl:call-template> | |
| </Legal_Last_Name> | |
| <!-- Country printed exactly as received --> | |
| <Location_Country> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" | |
| select="normalize-space(ws:Personal/ws:Address_Data/ws:Country)"/> | |
| </xsl:call-template> | |
| </Location_Country> | |
| <!-- Language derived from country --> | |
| <Language> | |
| <xsl:variable name="country" | |
| select="normalize-space(ws:Personal/ws:Address_Data/ws:Country)"/> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value"> | |
| <xsl:choose> | |
| <xsl:when test="$country = 'US'">ENG</xsl:when> | |
| <xsl:when test="$country = 'NL'">DUT</xsl:when> | |
| <xsl:when test="$country = 'DE'">GER</xsl:when> | |
| <xsl:when test="$country = 'FR'">FRE</xsl:when> | |
| <xsl:otherwise>NA</xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:with-param> | |
| </xsl:call-template> | |
| </Language> | |
| <!-- Work email --> | |
| <Work_Email> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" | |
| select="normalize-space(ws:Personal/ws:Email_Data/ws:Email_Address)"/> | |
| </xsl:call-template> | |
| </Work_Email> | |
| <!-- | |
| Current XML does not contain a separate | |
| home email node, so it remains blank. | |
| --> | |
| <Home_Email> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" select="''"/> | |
| </xsl:call-template> | |
| </Home_Email> | |
| <!-- Job profile --> | |
| <Job_Profile> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" | |
| select="normalize-space(ws:Position/ws:Job_Profile)"/> | |
| </xsl:call-template> | |
| </Job_Profile> | |
| <!-- Hire date: YYYY-MM-DD to DDMMYYYY --> | |
| <Hire_Date> | |
| <xsl:variable name="hireDate" | |
| select="normalize-space(ws:Status/ws:Hire_Date)"/> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value"> | |
| <xsl:call-template name="format-date"> | |
| <xsl:with-param name="date" | |
| select="$hireDate"/> | |
| </xsl:call-template> | |
| </xsl:with-param> | |
| </xsl:call-template> | |
| </Hire_Date> | |
| <!-- Termination date --> | |
| <Termination_Date> | |
| <xsl:variable name="terminationDate" | |
| select="normalize-space(ws:Status/ws:Termination_Date)"/> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value"> | |
| <xsl:call-template name="format-date"> | |
| <xsl:with-param name="date" | |
| select="$terminationDate"/> | |
| </xsl:call-template> | |
| </xsl:with-param> | |
| </xsl:call-template> | |
| </Termination_Date> | |
| <!-- | |
| Active: | |
| no termination date = true | |
| termination date present = false | |
| --> | |
| <Active> | |
| <xsl:choose> | |
| <xsl:when test=" | |
| normalize-space( | |
| ws:Status/ws:Termination_Date | |
| ) = '' | |
| "> | |
| <xsl:text>true</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:text>false</xsl:text> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </Active> | |
| <!-- Worker type printed exactly as received --> | |
| <Worker_Type> | |
| <xsl:call-template name="csv-value"> | |
| <xsl:with-param name="value" | |
| select="normalize-space(ws:Position/ws:Worker_Type)"/> | |
| </xsl:call-template> | |
| </Worker_Type> | |
| </Record> | |
| </xsl:for-each> | |
| </File> | |
| </xsl:template> | |
| <!-- ========================================================= | |
| Convert YYYY-MM-DD to DDMMYYYY. | |
| Missing or malformed dates return blank. | |
| ========================================================= --> | |
| <xsl:template name="format-date"> | |
| <xsl:param name="date"/> | |
| <xsl:choose> | |
| <xsl:when test=" | |
| string-length(normalize-space($date)) >= 10 | |
| and substring($date, 5, 1) = '-' | |
| and substring($date, 8, 1) = '-' | |
| "> | |
| <xsl:value-of select="substring($date, 9, 2)"/> | |
| <xsl:value-of select="substring($date, 6, 2)"/> | |
| <xsl:value-of select="substring($date, 1, 4)"/> | |
| </xsl:when> | |
| <xsl:otherwise/> | |
| </xsl:choose> | |
| </xsl:template> | |
| <!-- ========================================================= | |
| Wrap text fields in quotation marks. | |
| Missing values become "". | |
| Embedded quotes are doubled for CSV. | |
| ========================================================= --> | |
| <xsl:template name="csv-value"> | |
| <xsl:param name="value"/> | |
| <xsl:text>"</xsl:text> | |
| <xsl:call-template name="escape-quotes"> | |
| <xsl:with-param name="value" | |
| select="string($value)"/> | |
| </xsl:call-template> | |
| <xsl:text>"</xsl:text> | |
| </xsl:template> | |
| <!-- Convert " to "" inside CSV values --> | |
| <xsl:template name="escape-quotes"> | |
| <xsl:param name="value"/> | |
| <xsl:choose> | |
| <xsl:when test="contains($value, '"')"> | |
| <xsl:value-of | |
| select="substring-before($value, '"')"/> | |
| <xsl:text>""</xsl:text> | |
| <xsl:call-template name="escape-quotes"> | |
| <xsl:with-param name="value" | |
| select="substring-after($value, '"')"/> | |
| </xsl:call-template> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="$value"/> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:template> | |
| </xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment