This is a scenario-based example on Workday XSLT.
Background
It is very common for the integration team to deal with special characters either in inbound or outbound integrations. This is not only restricted to Workday but also in other ERP systems as well. Like Oracle Cloud, PeopleSoft etc. Recently one of my friends working in Oracle Cloud has raised this topic in a conversation.
Though this video/article is not limited to Workday, as I work in Workday system, I will talk more in terms of Workday as a background.
YouTube Video
Online XSLT Editor
https://www.freeformatter.com/xsl-transformer.html
1.XSLT: XML to XML (more appropriate for inbound integrations)
XML
<?xml version="1.0" encoding="UTF-8"?> <Root xmlns:ab="http://www.w3.org/TR/html4/"> <ab:Row> <ab:Employee_ID>1001</ab:Employee_ID> <ab:Name>Emma ©Dylan</ab:Name> <ab:Address1>750 — Austin - Secret Lane</ab:Address1> <ab:City>Salt Lake City</ab:City> <ab:State>NewYork </ab:State> <ab:Postal>84111</ab:Postal> </ab:Row> <ab:Row> <ab:Employee_ID>1002</ab:Employee_ID> <ab:Name>Jam'es Tyler</ab:Name> <ab:Address1>750 Austin Secret Lane</ab:Address1> <ab:City>Morristown¯</ab:City> <ab:State>Indiana</ab:State> <ab:Postal>46161</ab:Postal> </ab:Row> <ab:Row> <ab:Employee_ID>1003</ab:Employee_ID> <ab:Name>Oliver Parton!</ab:Name> <ab:Address1>4186 Green Hill Road</ab:Address1> <ab:City>Bentonville™</ab:City> <ab:State>Arkansas</ab:State> <ab:Postal>72712</ab:Postal> </ab:Row> </Root>
XSLT
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="*|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="text()"> <xsl:value-of select="normalize-space(replace(normalize-space(),'[^a-zA-Z0-9 ,]',''))"/> <!-- <xsl:value-of select="normalize-space()"/> --> </xsl:template> </xsl:stylesheet>
Output
<?xml version="1.0" encoding="UTF-8"?> <Root xmlns:ab="http://www.w3.org/TR/html4/"> <ab:Row> <ab:Employee_ID>1001</ab:Employee_ID> <ab:Name>Emma Dylan</ab:Name> <ab:Address1>750 Austin Secret Lane</ab:Address1> <ab:City>Salt Lake City</ab:City> <ab:State>NewYork</ab:State> <ab:Postal>84111</ab:Postal> </ab:Row> <ab:Row> <ab:Employee_ID>1002</ab:Employee_ID> <ab:Name>James Tyler</ab:Name> <ab:Address1>750 Austin Secret Lane</ab:Address1> <ab:City>Morristown</ab:City> <ab:State>Indiana</ab:State> <ab:Postal>46161</ab:Postal> </ab:Row> <ab:Row> <ab:Employee_ID>1003</ab:Employee_ID> <ab:Name>Oliver Parton</ab:Name> <ab:Address1>4186 Green Hill Road</ab:Address1> <ab:City>Bentonville</ab:City> <ab:State>Arkansas</ab:State> <ab:Postal>72712</ab:Postal> </ab:Row> </Root>
2.XSLT: XML to Text (more appropriate for outbound integrations)
XML
<?xml version="1.0" encoding="UTF-8"?> <Root xmlns:ab="http://www.w3.org/TR/html4/"> <ab:Row> <ab:Employee_ID>1001</ab:Employee_ID> <ab:Name>Emma ©Dylan</ab:Name> <ab:Address1>750 — Austin - Secret Lane</ab:Address1> <ab:City>Salt Lake City</ab:City> <ab:State>NewYork </ab:State> <ab:Postal>84111</ab:Postal> </ab:Row> <ab:Row> <ab:Employee_ID>1002</ab:Employee_ID> <ab:Name>Jam'es Tyler</ab:Name> <ab:Address1>750 Austin Secret Lane</ab:Address1> <ab:City>Morristown¯</ab:City> <ab:State>Indiana</ab:State> <ab:Postal>46161</ab:Postal> </ab:Row> <ab:Row> <ab:Employee_ID>1003</ab:Employee_ID> <ab:Name>Oliver Parton!</ab:Name> <ab:Address1>4186 Green Hill Road</ab:Address1> <ab:City>Bentonville™</ab:City> <ab:State>Arkansas</ab:State> <ab:Postal>72712</ab:Postal> </ab:Row> </Root>
XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ab="http://www.w3.org/TR/html4/" version="2.0"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:text>EmplID Name Address1 City State Postal </xsl:text> <xsl:text>
</xsl:text> <xsl:for-each select="Root/ab:Row"> <xsl:value-of select="substring(concat(normalize-space(replace(normalize-space(ab:Employee_ID),'[^a-zA-Z0-9 ,]','')),' '),1,12)"/> <xsl:value-of select="substring(concat(normalize-space(replace(normalize-space(ab:Name),'[^a-zA-Z0-9 ,]','')),' '),1,25)"/> <xsl:value-of select="substring(concat(normalize-space(replace(normalize-space(ab:Address1),'[^a-zA-Z0-9 ,]','')),' '),1,25)"/> <xsl:value-of select="substring(concat(normalize-space(replace(normalize-space(ab:City),'[^a-zA-Z0-9 ,]','')),' '),1,15)"/> <xsl:value-of select="substring(concat(normalize-space(replace(normalize-space(ab:State),'[^a-zA-Z0-9 ,]','')),' '),1,15)"/> <xsl:value-of select="substring(concat(normalize-space(replace(normalize-space(ab:Postal),'[^a-zA-Z0-9 ,]','')),' '),1,15)"/> <xsl:text>
</xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
Output
EmplID Name Address1 City State Postal 1001 Emma Dylan 750 Austin Secret Lane Salt Lake City NewYork 84111 1002 James Tyler 750 Austin Secret Lane Morristown Indiana 46161 1003 Oliver Parton 4186 Green Hill Road Bentonville Arkansas 72712
3.Solving the problem at the root
In the above two scenarios, we are trying to address the issue in the integrating level. I feel the best way of solving the issue is at the root.
As Workday HCM system will be the source of truth for HCM data, it is better to correct the data in the system itself.
How would the special characters enter into the system
There could be many reasons why special characters come into the system.
One scenario is, if we are using resume scraping to read text, unwanted and unintended characters will be fed into the system.
The other scenario is, the person entering data is copying data from a website or some other source. At that point also there is a possibility of special characters being introduced unintentionally.
Solution
I have implemented a report which will look for special characters in names and addresses. I called it Special Characters Audit Report. It will output all employees with special characters in either Name or Address. I have scheduled it on a daily basis at 8 am and sent the output to business users (completely avoiding IT Team). This has improved the overall quality of the data and reduced integration failures (at workday side or the vendor side) by at least 30%.