Useful Workday XSLT snippets

Posted 2 years ago

These are XSLT snippets and code samples that I've frequently needed to Google or look back at old projects for (this was pre-ChatGPT). Click each dropdown to expand the section and see it's code.

PSA: ChatGPT is VERY good at generating XSLT

Variables & Functions

Reusable field separator and new line variables
<xsl:variable name="sep" select="','"/>
<xsl:variable name="nl" select="'&#10;'"/>
Single and double quote characters
<xsl:variable name="quote" select="'&quot;'"/>
<xsl:variable name="dbl-quote" select="'&quot;&quot;'"/>
Simple function to csv-ify a field
<xsl:function name="g:csv-ify">
    <xsl:param name="str1"/>
    <xsl:value-of select="concat($quote,replace($str1,$quote,$dbl-quote),$quote)"/>
</xsl:function>
Preserve/add a comment with XML output XSLT:
<xsl:comment>Company ID</xsl:comment>
XML Result:
<!--Company ID-->
Subtract 1 day from a date
<!-- Custom XSLT function to subtract 1 day from a date -->
<xsl:function name="sg:subtractOneDay" as="xs:string">
    <xsl:param name="inputDate" as="xs:string"/>
    <xsl:variable name="oneDay" select="xs:dayTimeDuration('P1D')"/>
    <xsl:choose>
        <!-- If the date is blank, return {empty} -->
        <xsl:when test="normalize-space($inputDate) = ''">
            <xsl:sequence select="$blank"/>
        </xsl:when>
        <!-- Subtract one day from the date -->
        <xsl:otherwise>
            <xsl:sequence
                select="sg:substringDate(xs:string(xs:dateTime($inputDate) - $oneDay))"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:function>

Useful templates

Remove all namsepace attributes from an xml file
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <!-- Copy all nodes and attributes -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Remove namespace declarations from elements -->
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>
Select the most recent node in a group of similar nodes This example would select the most recent `Report_Entry` for each `User_Code` as ordered by `Hire_Date`
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wd="urn:com.workday.report/Some_Report"
    xmlns:xtt="urn:com.workday/xtt" exclude-result-prefixes="xs" xmlns:g="sglmr.com" version="2.0">

    <!-- Variables -->
    <xsl:variable name="sep" select="','"/>
    <xsl:variable name="nl" select="'&#10;'"/>
    <xsl:variable name="quote" select="'&quot;'" />
    <xsl:variable name="dbl-quote" select="'&quot;&quot;'"/>

    <!-- Functions -->
    <xsl:function name="g:csv-ify">
        <xsl:param name="str1"/>
        <xsl:value-of select="concat($quote,replace($str1,$quote,$dbl-quote),$quote)"/>
    </xsl:function>

   <!-- Processing "settings" -->
    <xsl:output method="text"/>
    <xsl:strip-space elements="*" />

    <!-- Start of transformation -->
    <xsl:template match="/">
        <!-- Header -->
        <xsl:text>Field 1, Field 2, Field 3, etc..</xsl:text>
        <!-- Group all the Report Entries by wd:User_Code (Employee ID) -->
        <xsl:for-each-group select="/wd:Report_Data/wd:Report_Entry" group-by="wd:User_Code">
            <!-- Only process the node with the most recent hire date -->
            <xsl:for-each select="current-group()[xs:date(wd:Hire_Date) = max(current-group()/xs:date(wd:Hire_Date))]">
                <xsl:value-of select="$nl"/>
                <xsl:value-of select="g:csv-ify(wd:Field_1)"/>
                <xsl:value-of select="$sep"/>
                <xsl:value-of select="g:csv-ify(wd:Field_2)"/>
                <xsl:value-of select="$sep"/>
                <xsl:value-of select="g:csv-ify(wd:Field_3)"/>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>
Pretty print XML conversion
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wd="urn:com.workday/bsvc">
    <!-- indent=Yes for Pretty Print -->
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <!-- Identity template copies everything
    that doesn't match another template -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
Convert characters to ascii
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

     <xsl:output method="xml" indent="yes"/>
     <xsl:output use-character-maps="AsciiEquivalents"/>

     <xsl:template match="/">
          <File xtt:separator=" ">
               <Data></Data>
          </File>
     </xsl>


     <xsl:character-map name="AsciiEquivalents">
          <!-- 
               Latin-1 Supplement         
            -->
          <xsl:output-character character="$" string=""/>
          <xsl:output-character character="" string=""/>
          <xsl:output-character character="‚" string=""/>
          <xsl:output-character character="ƒ" string=""/>
          <xsl:output-character character="„" string=""/>
          <xsl:output-character character="…" string=""/>
          <xsl:output-character character="†" string=""/>
          <xsl:output-character character="‡" string=""/>
          <xsl:output-character character="ˆ" string=""/>
          <xsl:output-character character="‰" string=""/>
          <xsl:output-character character="Š" string=""/>
          <xsl:output-character character="‹" string=""/>
          <xsl:output-character character="Œ" string=""/>
          <xsl:output-character character="" string=""/>
          <xsl:output-character character="Ž" string=""/>
          <xsl:output-character character="" string=""/>
          <xsl:output-character character="" string=""/>
          <xsl:output-character character="‘" string=""/>
          <xsl:output-character character="’" string=""/>
          <xsl:output-character character="“" string=""/>
          <xsl:output-character character="”" string=""/>
          <xsl:output-character character="•" string=""/>
          <xsl:output-character character="–" string=""/>
          <xsl:output-character character="—" string=""/>
          <xsl:output-character character="˜" string=""/>
          <xsl:output-character character="™" string=""/>
          <xsl:output-character character="š" string=""/>
          <xsl:output-character character="›" string=""/>
          <xsl:output-character character="œ" string=""/>
          <xsl:output-character character="" string=""/>
          <xsl:output-character character="ž" string=""/>
          <xsl:output-character character="Ÿ" string=""/>
          <xsl:output-character character=" " string=" "/>
          <!--  Non-breaking space  -->
          <xsl:output-character character="¡" string=""/>
          <!--  ! may be an option  -->
          <xsl:output-character character="¢" string=""/>
          <!--  C/ may be acceptable  -->
          <xsl:output-character character="£" string=""/>
          <!--  Translating to GBP might be acceptable if guaranteed usage only for British Pound  -->
          <xsl:output-character character="¤" string=""/>
          <xsl:output-character character="¥" string=""/>
          <!--  Y= may be acceptable  -->
          <xsl:output-character character="¦" string="|"/>
          <xsl:output-character character="§" string=""/>
          <!--  SS may be an option  -->
          <xsl:output-character character="¨" string=" "/>
          <xsl:output-character character="©" string="(c)"/>
          <xsl:output-character character="ª" string="a"/>
          <xsl:output-character character="«" string="<<"/>
          <!--  Using a &quot; might be preferable for some usages -->
          <xsl:output-character character="¬" string=""/>
          <xsl:output-character character="­" string="-"/>
          <xsl:output-character character="®" string="(r)"/>
          <xsl:output-character character="¯" string=""/>
          <xsl:output-character character="°" string=""/>
          <!--  Depending on usage you may be able to use deg -->
          <xsl:output-character character="±" string="+/-"/>
          <xsl:output-character character="²" string="2"/>
          <xsl:output-character character="³" string="3"/>
          <xsl:output-character character="´" string=" "/>
          <xsl:output-character character="µ" string="u"/>
          <xsl:output-character character="¶" string=""/>
          <xsl:output-character character="·" string="*"/>
          <xsl:output-character character="¸" string=","/>
          <xsl:output-character character="¹" string="1"/>
          <xsl:output-character character="º" string="o"/>
          <xsl:output-character character="»" string=">>"/>
          <!--  Using a &quot; might be preferable for some usages  -->
          <xsl:output-character character="¼" string="1⁄4"/>
          <xsl:output-character character="½" string="1⁄2"/>
          <xsl:output-character character="¾" string="3⁄4"/>
          <xsl:output-character character="¿" string="?"/>
          <xsl:output-character character="À" string="A"/>
          <xsl:output-character character="Á" string="A"/>
          <xsl:output-character character="Â" string="A"/>
          <xsl:output-character character="Ã" string="A"/>
          <xsl:output-character character="Ä" string="Ae"/>
          <!--  This is the German equivalent which is the most likely to be encountered.  -->
          <xsl:output-character character="Å" string="Aa"/>
          <!--  Swedish transcription  -->
          <xsl:output-character character="Æ" string="Ae"/>
          <xsl:output-character character="Ç" string="C"/>
          <xsl:output-character character="È" string="E"/>
          <xsl:output-character character="É" string="E"/>
          <xsl:output-character character="Ê" string="E"/>
          <xsl:output-character character="Ë" string="E"/>
          <xsl:output-character character="Ì" string="I"/>
          <xsl:output-character character="Í" string="I"/>
          <xsl:output-character character="Î" string="I"/>
          <xsl:output-character character="Ï" string="I"/>
          <xsl:output-character character="Ð" string="D"/>
          <xsl:output-character character="Ñ" string="N"/>
          <xsl:output-character character="Ò" string="O"/>
          <xsl:output-character character="Ó" string="O"/>
          <xsl:output-character character="Ô" string="O"/>
          <xsl:output-character character="Õ" string="O"/>
          <xsl:output-character character="Ö" string="Oe"/>
          <!--  This is the German and Swedish equivalent which is the most likely to be encountered.  Finnish would use O  -->
          <xsl:output-character character="×" string="×"/>
          <xsl:output-character character="Ø" string="Oe"/>
          <!--  This is the Swedish equivalent which is the most likely to be encountered.  Usage should be fine for Norwegian and Danish  -->
          <xsl:output-character character="Ù" string="U"/>
          <xsl:output-character character="Ú" string="U"/>
          <xsl:output-character character="Û" string="U"/>
          <xsl:output-character character="Ü" string="Ue"/>
          <!--  This is the German equivalent which is the most likely to be encountered.  Other languages may use U  -->
          <xsl:output-character character="Ý" string="Y"/>
          <xsl:output-character character="Þ" string="Th"/>
          <xsl:output-character character="ß" string="ss"/>
          <xsl:output-character character="à" string="a"/>
          <xsl:output-character character="á" string="a"/>
          <xsl:output-character character="â" string="a"/>
          <xsl:output-character character="ã" string="a"/>
          <xsl:output-character character="ä" string="ae"/>
          <!--  This is the German equivalent which is the most likely to be encountered  -->
          <xsl:output-character character="å" string="a"/>
          <xsl:output-character character="æ" string="ae"/>
          <xsl:output-character character="ç" string="c"/>
          <xsl:output-character character="è" string="e"/>
          <xsl:output-character character="é" string="e"/>
          <xsl:output-character character="ê" string="e"/>
          <xsl:output-character character="ë" string="e"/>
          <xsl:output-character character="ì" string="i"/>
          <xsl:output-character character="í" string="i"/>
          <xsl:output-character character="í" string="i"/>
          <xsl:output-character character="î" string="i"/>
          <xsl:output-character character="ï" string="i"/>
          <xsl:output-character character="ð" string="d"/>
          <xsl:output-character character="ñ" string="n"/>
          <xsl:output-character character="ò" string="o"/>
          <xsl:output-character character="ó" string="o"/>
          <xsl:output-character character="ô" string="o"/>
          <xsl:output-character character="õ" string="o"/>
          <xsl:output-character character="ö" string="oe"/>
          <!--  This is the German equivalent which is the most likely to be encountered  -->
          <xsl:output-character character="÷" string="/"/>
          <xsl:output-character character="ø" string="oe"/>
          <!--  This is the Swedish equivalent which is the most likely to be encountered.  Usage should be fine for Norwegian and Danish  -->
          <xsl:output-character character="ù" string="u"/>
          <xsl:output-character character="ú" string="u"/>
          <xsl:output-character character="û" string="u"/>
          <xsl:output-character character="ü" string="ue"/>
          <!--  This is the German equivalent which is the most likely to be encountered  -->
          <xsl:output-character character="ý" string="y"/>
          <xsl:output-character character="þ" string="th"/>
          <xsl:output-character character="ÿ" string="y"/>
          <!-- 
               Latin Extended-A    
            -->
          <xsl:output-character character="Ā" string="A"/>
          <xsl:output-character character="ā" string="a"/>
          <xsl:output-character character="Ă" string="A"/>
          <xsl:output-character character="ă" string="a"/>
          <xsl:output-character character="Ą" string="A"/>
          <xsl:output-character character="ą" string="a"/>
          <xsl:output-character character="Ć" string="C"/>
          <xsl:output-character character="ć" string="c"/>
          <xsl:output-character character="Ĉ" string="C"/>
          <xsl:output-character character="ĉ" string="c"/>
          <xsl:output-character character="Ċ" string="C"/>
          <xsl:output-character character="ċ" string="c"/>
          <xsl:output-character character="Č" string="C"/>
          <xsl:output-character character="č" string="c"/>
          <xsl:output-character character="Ď" string="D"/>
          <xsl:output-character character="ď" string="d"/>
          <xsl:output-character character="Đ" string="Dj"/>
          <!--  This is the Serbian equivalent, Macedonian would use Gj  -->
          <xsl:output-character character="đ" string="dj"/>
          <!--  This is the Serbian equivalent, Macedonian would use Gj  -->
          <xsl:output-character character="Ē" string="E"/>
          <xsl:output-character character="ē" string="e"/>
          <xsl:output-character character="Ĕ" string="E"/>
          <xsl:output-character character="ĕ" string="e"/>
          <xsl:output-character character="Ė" string="E"/>
          <xsl:output-character character="ė" string="e"/>
          <xsl:output-character character="Ę" string="E"/>
          <xsl:output-character character="ę" string="e"/>
          <xsl:output-character character="Ě" string="E"/>
          <xsl:output-character character="ě" string="e"/>
          <xsl:output-character character="Ĝ" string="G"/>
          <xsl:output-character character="ĝ" string="g"/>
          <xsl:output-character character="Ğ" string="G"/>
          <xsl:output-character character="ğ" string="g"/>
          <xsl:output-character character="Ġ" string="G"/>
          <xsl:output-character character="ġ" string="g"/>
          <xsl:output-character character="Ģ" string="G"/>
          <xsl:output-character character="ģ" string="g"/>
          <xsl:output-character character="Ĥ" string="H"/>
          <xsl:output-character character="ĥ" string="h"/>
          <xsl:output-character character="Ħ" string="H"/>
          <xsl:output-character character="ħ" string="h"/>
          <xsl:output-character character="Ĩ" string="I"/>
          <xsl:output-character character="ĩ" string="i"/>
          <xsl:output-character character="Ī" string="I"/>
          <xsl:output-character character="ī" string="i"/>
          <xsl:output-character character="Ĭ" string="I"/>
          <xsl:output-character character="ĭ" string="i"/>
          <xsl:output-character character="Į" string="I"/>
          <xsl:output-character character="į" string="i"/>
          <xsl:output-character character="İ" string="I"/>
          <xsl:output-character character="ı" string="I"/>
          <xsl:output-character character="IJ" string="IJ"/>
          <xsl:output-character character="ij" string="ij"/>
          <xsl:output-character character="Ĵ" string="J"/>
          <xsl:output-character character="ĵ" string="j"/>
          <xsl:output-character character="Ķ" string="K"/>
          <xsl:output-character character="ķ" string="k"/>
          <xsl:output-character character="ĸ" string="q"/>
          <xsl:output-character character="Ĺ" string="L"/>
          <xsl:output-character character="ĺ" string="l"/>
          <xsl:output-character character="Ļ" string="L"/>
          <xsl:output-character character="ļ" string="l"/>
          <xsl:output-character character="Ľ" string="L"/>
          <xsl:output-character character="ľ" string="l"/>
          <xsl:output-character character="Ŀ" string="L."/>
          <!--  Catalan punt volat, a hyphen may also be used instead of a period  -->
          <xsl:output-character character="ŀ" string="l."/>
          <!--  Catalan punt volat, a hyphen may also be used instead of a period  -->
          <xsl:output-character character="Ł" string="L"/>
          <xsl:output-character character="ł" string="l"/>
          <xsl:output-character character="Ń" string="N"/>
          <xsl:output-character character="ń" string="n"/>
          <xsl:output-character character="Ņ" string="N"/>
          <xsl:output-character character="ņ" string="n"/>
          <xsl:output-character character="Ň" string="N"/>
          <xsl:output-character character="ň" string="n"/>
          <xsl:output-character character="ʼn" string="n"/>
          <xsl:output-character character="Ŋ" string="Ng"/>
          <!--  May vary depending on specific transliteration for languages that use the African Reference Alphabet  -->
          <xsl:output-character character="ŋ" string="ng"/>
          <!--  May vary depending on specific transliteration for languages that use the African Reference Alphabet  -->
          <xsl:output-character character="Ō" string="O"/>
          <xsl:output-character character="ō" string="o"/>
          <xsl:output-character character="Ŏ" string="O"/>
          <xsl:output-character character="ŏ" string="o"/>
          <xsl:output-character character="Ő" string="O"/>
          <xsl:output-character character="ő" string="o"/>
          <xsl:output-character character="Œ" string="Oe"/>
          <xsl:output-character character="œ" string="oe"/>
          <xsl:output-character character="Ŕ" string="R"/>
          <xsl:output-character character="ŕ" string="r"/>
          <xsl:output-character character="Ŗ" string="R"/>
          <xsl:output-character character="ŗ" string="r"/>
          <xsl:output-character character="Ř" string="R"/>
          <xsl:output-character character="ř" string="r"/>
          <xsl:output-character character="Ś" string="S"/>
          <xsl:output-character character="ś" string="s"/>
          <xsl:output-character character="Ŝ" string="S"/>
          <xsl:output-character character="ŝ" string="s"/>
          <xsl:output-character character="Ş" string="S"/>
          <xsl:output-character character="ş" string="s"/>
          <xsl:output-character character="Š" string="Sh"/>
          <xsl:output-character character="š" string="sh"/>
          <xsl:output-character character="Ţ" string="T"/>
          <xsl:output-character character="ţ" string="t"/>
          <xsl:output-character character="Ť" string="T"/>
          <xsl:output-character character="ť" string="t"/>
          <xsl:output-character character="Ŧ" string="T"/>
          <xsl:output-character character="ŧ" string="t"/>
          <xsl:output-character character="Ũ" string="U"/>
          <xsl:output-character character="ũ" string="u"/>
          <xsl:output-character character="Ū" string="U"/>
          <xsl:output-character character="ū" string="u"/>
          <xsl:output-character character="Ŭ" string="U"/>
          <xsl:output-character character="ŭ" string="u"/>
          <xsl:output-character character="Ů" string="U"/>
          <xsl:output-character character="ů" string="u"/>
          <xsl:output-character character="Ű" string="U"/>
          <xsl:output-character character="ű" string="u"/>
          <xsl:output-character character="Ų" string="U"/>
          <xsl:output-character character="ų" string="u"/>
          <xsl:output-character character="Ŵ" string="W"/>
          <xsl:output-character character="ŵ" string="w"/>
          <xsl:output-character character="Ŷ" string="Y"/>
          <xsl:output-character character="ŷ" string="y"/>
          <xsl:output-character character="Ÿ" string="Y"/>
          <xsl:output-character character="Ź" string="Z"/>
          <xsl:output-character character="ź" string="z"/>
          <xsl:output-character character="Ż" string="Z"/>
          <xsl:output-character character="ż" string="z"/>
          <xsl:output-character character="Ž" string="Z"/>
          <xsl:output-character character="ž" string="z"/>
          <xsl:output-character character="ſ" string="s"/>
          <!-- 
             Latin Extended-B
            -->
          <xsl:output-character character="ƀ" string="b"/>
          <xsl:output-character character="Ɓ" string="B"/>
          <xsl:output-character character="Ƃ" string="B"/>
          <xsl:output-character character="ƃ" string="b"/>
          <xsl:output-character character="Ƅ" string="6"/>
          <xsl:output-character character="ƅ" string="6"/>
          <xsl:output-character character="Ɔ" string="0"/>
          <xsl:output-character character="Ƈ" string="C"/>
          <xsl:output-character character="ƈ" string="c"/>
          <xsl:output-character character="Ɖ" string="D"/>
          <xsl:output-character character="Ɗ" string="D"/>
          <xsl:output-character character="Ƌ" string="D"/>
          <xsl:output-character character="ƌ" string="d"/>
          <xsl:output-character character="ƍ" string="d"/>
          <xsl:output-character character="Ǝ" string="3"/>
          <xsl:output-character character="Ə" string="@"/>
          <xsl:output-character character="Ɛ" string="E"/>
          <xsl:output-character character="Ƒ" string="F"/>
          <xsl:output-character character="ƒ" string="f"/>
          <xsl:output-character character="Ɠ" string="G"/>
          <xsl:output-character character="Ɣ" string="G"/>
          <xsl:output-character character="ƕ" string="hv"/>
          <xsl:output-character character="Ɩ" string="I"/>
          <xsl:output-character character="Ɨ" string="I"/>
          <xsl:output-character character="Ƙ" string="K"/>
          <xsl:output-character character="ƙ" string="k"/>
          <xsl:output-character character="ƚ" string="l"/>
          <xsl:output-character character="ƛ" string="l"/>
          <xsl:output-character character="Ɯ" string="W"/>
          <xsl:output-character character="Ɲ" string="N"/>
          <xsl:output-character character="ƞ" string="n"/>
          <xsl:output-character character="Ɵ" string="O"/>
          <xsl:output-character character="Ơ" string="O"/>
          <xsl:output-character character="ơ" string="o"/>
          <xsl:output-character character="Ƣ" string="OI"/>
          <xsl:output-character character="ƣ" string="oi"/>
          <xsl:output-character character="Ƥ" string="P"/>
          <xsl:output-character character="ƥ" string="p"/>
          <xsl:output-character character="Ʀ" string="YR"/>
          <xsl:output-character character="Ƨ" string="2"/>
          <xsl:output-character character="ƨ" string="2"/>
          <xsl:output-character character="Ʃ" string="SH"/>
          <xsl:output-character character="ƪ" string="sh"/>
          <xsl:output-character character="ƫ" string="t"/>
          <xsl:output-character character="Ƭ" string="T"/>
          <xsl:output-character character="ƭ" string="t"/>
          <xsl:output-character character="Ʈ" string="T"/>
          <xsl:output-character character="Ư" string="U"/>
          <xsl:output-character character="ư" string="u"/>
          <xsl:output-character character="Ʊ" string="Y"/>
          <xsl:output-character character="Ʋ" string="V"/>
          <xsl:output-character character="Ƴ" string="Y"/>
          <xsl:output-character character="ƴ" string="y"/>
          <xsl:output-character character="Ƶ" string="Z"/>
          <xsl:output-character character="ƶ" string="z"/>
          <xsl:output-character character="Ʒ" string="ZH"/>
          <xsl:output-character character="Ƹ" string="ZH"/>
          <xsl:output-character character="ƹ" string="zh"/>
          <xsl:output-character character="ƺ" string="zh"/>
          <xsl:output-character character="ƻ" string="2"/>
          <xsl:output-character character="Ƽ" string="5"/>
          <xsl:output-character character="ƽ" string="5"/>
          <xsl:output-character character="ƾ" string="ts"/>
          <xsl:output-character character="ƿ" string="w"/>
          <xsl:output-character character="ǀ" string="|"/>
          <xsl:output-character character="ǁ" string="||"/>
          <xsl:output-character character="ǂ" string="!="/>
          <xsl:output-character character="ǃ" string="!"/>
          <xsl:output-character character="DŽ" string="DZ"/>
          <xsl:output-character character="Dž" string="Dz"/>
          <xsl:output-character character="dž" string="dz"/>
          <xsl:output-character character="LJ" string="LJ"/>
          <xsl:output-character character="Lj" string="Lj"/>
          <xsl:output-character character="lj" string="lj"/>
          <xsl:output-character character="NJ" string="NJ"/>
          <xsl:output-character character="Nj" string="Nj"/>
          <xsl:output-character character="nj" string="nj"/>
          <xsl:output-character character="Ǎ" string="A"/>
          <xsl:output-character character="ǎ" string="a"/>
          <xsl:output-character character="Ǐ" string="I"/>
          <xsl:output-character character="ǐ" string="i"/>
          <xsl:output-character character="Ǒ" string="O"/>
          <xsl:output-character character="ǒ" string="o"/>
          <xsl:output-character character="Ǔ" string="U"/>
          <xsl:output-character character="ǔ" string="u"/>
          <xsl:output-character character="Ǖ" string="U"/>
          <xsl:output-character character="ǖ" string="u"/>
          <xsl:output-character character="Ǘ" string="Ü"/>
          <xsl:output-character character="ǘ" string="u"/>
          <xsl:output-character character="Ǚ" string="U"/>
          <xsl:output-character character="ǚ" string="u"/>
          <xsl:output-character character="Ǜ" string="U"/>
          <xsl:output-character character="ǜ" string="u"/>
          <xsl:output-character character="ǝ" string="@"/>
          <xsl:output-character character="Ǟ" string="A"/>
          <xsl:output-character character="ǟ" string="a"/>
          <xsl:output-character character="Ǡ" string="A"/>
          <xsl:output-character character="ǡ" string="a"/>
          <xsl:output-character character="Ǣ" string="Ae"/>
          <xsl:output-character character="ǣ" string="ae"/>
          <xsl:output-character character="Ǥ" string="G"/>
          <xsl:output-character character="ǥ" string="g"/>
          <xsl:output-character character="Ǧ" string="G"/>
          <xsl:output-character character="ǧ" string="g"/>
          <xsl:output-character character="Ǩ" string="K"/>
          <xsl:output-character character="ǩ" string="k"/>
          <xsl:output-character character="Ǫ" string="O"/>
          <xsl:output-character character="ǫ" string="o"/>
          <xsl:output-character character="Ǭ" string="O"/>
          <xsl:output-character character="ǭ" string="o"/>
          <xsl:output-character character="Ǯ" string="ZH"/>
          <xsl:output-character character="ǯ" string="zh"/>
          <xsl:output-character character="ǰ" string="j"/>
          <xsl:output-character character="DZ" string="DZ"/>
          <xsl:output-character character="Dz" string="Dz"/>
          <xsl:output-character character="dz" string="dz"/>
          <xsl:output-character character="Ǵ" string="G"/>
          <xsl:output-character character="ǵ" string="g"/>
          <xsl:output-character character="Ƕ" string="HV"/>
          <xsl:output-character character="Ƿ" string="W"/>
          <xsl:output-character character="Ǹ" string="N"/>
          <xsl:output-character character="ǹ" string="n"/>
          <xsl:output-character character="Ǻ" string="A"/>
          <xsl:output-character character="ǻ" string="a"/>
          <xsl:output-character character="Ǽ" string="Ae"/>
          <xsl:output-character character="ǽ" string="ae"/>
          <xsl:output-character character="Ǿ" string="O"/>
          <xsl:output-character character="ǿ" string="o"/>
          <xsl:output-character character="Ȁ" string="A"/>
          <xsl:output-character character="ȁ" string="a"/>
          <xsl:output-character character="Ȃ" string="A"/>
          <xsl:output-character character="ȃ" string="a"/>
          <xsl:output-character character="Ȅ" string="E"/>
          <xsl:output-character character="ȅ" string="e"/>
          <xsl:output-character character="Ȇ" string="E"/>
          <xsl:output-character character="ȇ" string="e"/>
          <xsl:output-character character="Ȉ" string="I"/>
          <xsl:output-character character="ȉ" string="i"/>
          <xsl:output-character character="Ȋ" string="I"/>
          <xsl:output-character character="ȋ" string="i"/>
          <xsl:output-character character="Ȍ" string="O"/>
          <xsl:output-character character="ȍ" string="o"/>
          <xsl:output-character character="Ȏ" string="O"/>
          <xsl:output-character character="ȏ" string="o"/>
          <xsl:output-character character="Ȑ" string="R"/>
          <xsl:output-character character="ȑ" string="r"/>
          <xsl:output-character character="Ȓ" string="R"/>
          <xsl:output-character character="ȓ" string="r"/>
          <xsl:output-character character="Ȕ" string="U"/>
          <xsl:output-character character="ȕ" string="u"/>
          <xsl:output-character character="Ȗ" string="U"/>
          <xsl:output-character character="ȗ" string="u"/>
          <xsl:output-character character="Ș" string="S"/>
          <xsl:output-character character="ș" string="s"/>
          <xsl:output-character character="Ț" string="T"/>
          <xsl:output-character character="ț" string="t"/>
          <xsl:output-character character="Ȝ" string="Y"/>
          <xsl:output-character character="ȝ" string="y"/>
          <xsl:output-character character="Ȟ" string="H"/>
          <xsl:output-character character="ȟ" string="h"/>
          <xsl:output-character character="Ƞ" string="N"/>
          <xsl:output-character character="ȡ" string="d"/>
          <xsl:output-character character="Ȣ" string="OU"/>
          <xsl:output-character character="ȣ" string="ou"/>
          <xsl:output-character character="Ȥ" string="Z"/>
          <xsl:output-character character="ȥ" string="z"/>
          <xsl:output-character character="Ȧ" string="A"/>
          <xsl:output-character character="ȧ" string="a"/>
          <xsl:output-character character="Ȩ" string="E"/>
          <xsl:output-character character="ȩ" string="e"/>
          <xsl:output-character character="Ȫ" string="O"/>
          <xsl:output-character character="ȫ" string="o"/>
          <xsl:output-character character="Ȭ" string="O"/>
          <xsl:output-character character="ȭ" string="o"/>
          <xsl:output-character character="Ȯ" string="O"/>
          <xsl:output-character character="ȯ" string="o"/>
          <xsl:output-character character="Ȱ" string="O"/>
          <xsl:output-character character="ȱ" string="o"/>
          <xsl:output-character character="Ȳ" string="Y"/>
          <xsl:output-character character="ȳ" string="y"/>
          <xsl:output-character character="ȴ" string="l"/>
          <xsl:output-character character="ȵ" string="n"/>
          <xsl:output-character character="ȶ" string="t"/>
          <xsl:output-character character="ȷ" string="j"/>
          <xsl:output-character character="ȸ" string="db"/>
          <xsl:output-character character="ȹ" string="qp"/>
          <xsl:output-character character="Ⱥ" string="A"/>
          <xsl:output-character character="Ȼ" string="C"/>
          <xsl:output-character character="ȼ" string="c"/>
          <xsl:output-character character="Ƚ" string="L"/>
          <xsl:output-character character="Ⱦ" string="T"/>
          <xsl:output-character character="ȿ" string="s"/>
          <xsl:output-character character="ɀ" string="z"/>
          <xsl:output-character character="Ɂ" string="[?]"/>
          <xsl:output-character character="ɂ" string="[?]"/>
          <xsl:output-character character="Ƀ" string="B"/>
          <xsl:output-character character="Ʉ" string="U"/>
          <xsl:output-character character="Ʌ" string="^"/>
          <xsl:output-character character="Ɇ" string="E"/>
          <xsl:output-character character="ɇ" string="e"/>
          <xsl:output-character character="Ɉ" string="J"/>
          <xsl:output-character character="ɉ" string="j"/>
          <xsl:output-character character="Ɋ" string="Q"/>
          <xsl:output-character character="ɋ" string="q"/>
          <xsl:output-character character="Ɍ" string="R"/>
          <xsl:output-character character="ɍ" string="r"/>
          <xsl:output-character character="Ɏ" string="Y"/>
          <xsl:output-character character="ɏ" string="y"/>
     </xsl:character-map>

</xsl:stylesheet>
XSD Schema generation
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsl:output method="xml" indent="yes" />
  <!-- Generate XSD schema element -->
  <xsl:template match="/">
    <xsd:schema>
      <xsl:apply-templates />
    </xsd:schema>
  </xsl:template>
  <!-- Generate element declaration for each element -->
  <xsl:template match="*">
    <xsd:element name="{name()}">
      <xsl:apply-templates select="@*" />
      <xsl:choose>
        <xsl:when test="*">
          <xsd:complexType>
            <xsd:sequence>
              <xsl:apply-templates select="*" />
            </xsd:sequence>
            <xsl:apply-templates select="@* except xml:id" />
          </xsd:complexType>
        </xsl:when>
        <xsl:otherwise>
          <xsd:simpleType>
            <xsd:restriction base="xsd:string" />
          </xsd:simpleType>
          <xsl:apply-templates select="@* except xml:id" />
        </xsl:otherwise>
      </xsl:choose>
    </xsd:element>
  </xsl:template>
  <!-- Generate attribute declaration for each attribute -->
  <xsl:template match="@*">
    <xsd:attribute name="{name()}" type="xsd:string" />
  </xsl:template>
</xsl:stylesheet>