Workday XSLT - Replace special Characters

Workday XSLT - Replace special Characters

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>&#xa;</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>&#xa;</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%.