Skip to content

Instantly share code, notes, and snippets.

@r4hulp
Created July 13, 2026 10:35
Show Gist options
  • Select an option

  • Save r4hulp/c2655b9da47ab7f94d0e8a432976b002 to your computer and use it in GitHub Desktop.

Select an option

Save r4hulp/c2655b9da47ab7f94d0e8a432976b002 to your computer and use it in GitHub Desktop.
<?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">
<xsl:output
method="xml"
encoding="UTF-8"
omit-xml-declaration="no"
indent="yes"/>
<xsl:template match="/">
<!--
Root separator:
places the header and every worker record
on separate lines in the final CSV.
-->
<File xtt:separator="&#xD;&#xA;">
<!-- CSV header -->
<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 CSV row for every Worker -->
<xsl:for-each select="ws:Worker_Sync/ws:Worker">
<xsl:variable name="country"
select="normalize-space(
ws:Personal/ws:Address_Data/ws:Country
)"/>
<xsl:variable name="hireDate"
select="normalize-space(
ws:Status/ws:Hire_Date
)"/>
<xsl:variable name="terminationDate"
select="normalize-space(
ws:Status/ws:Termination_Date
)"/>
<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 as received -->
<Location_Country>
<xsl:call-template name="csv-value">
<xsl:with-param
name="value"
select="$country"/>
</xsl:call-template>
</Location_Country>
<!-- Language mapping -->
<Language>
<xsl:call-template name="csv-value">
<xsl:with-param name="value">
<xsl:choose>
<xsl:when test="$country = 'US'">
<xsl:text>ENG</xsl:text>
</xsl:when>
<xsl:when test="$country = 'NL'">
<xsl:text>DUT</xsl:text>
</xsl:when>
<xsl:when test="$country = 'DE'">
<xsl:text>GER</xsl:text>
</xsl:when>
<xsl:when test="$country = 'FR'">
<xsl:text>FRE</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>NA</xsl:text>
</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>
<!-- Home email currently unavailable separately -->
<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 -->
<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: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 -->
<Active>
<xsl:choose>
<xsl:when test="$terminationDate = ''">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</Active>
<!-- Worker Type printed 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 -->
<xsl:template name="format-date">
<xsl:param name="date"/>
<xsl:choose>
<xsl:when test="
string-length(normalize-space($date)) &gt;= 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>
<!-- Quote every text value for valid 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>
<!-- Escape embedded quotation marks -->
<xsl:template name="escape-quotes">
<xsl:param name="value"/>
<xsl:choose>
<xsl:when test="contains($value, '&quot;')">
<xsl:value-of
select="substring-before($value, '&quot;')"/>
<xsl:text>""</xsl:text>
<xsl:call-template name="escape-quotes">
<xsl:with-param
name="value"
select="substring-after(
$value,
'&quot;'
)"/>
</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