0

I use XSLT v1.0 and want to translate "UÅ1atx-ß3Å" to "UAA1atx-SS3AA" which "Å" = 'AA' and "ß" = "SS", but so far no luck.

I only can change lower-case to upper-case and remove none alphanumeric characters , not replace with the character that I want to replace.

variable name="OddChars">ÄÖÅÜÉäöåüé variable name="RegChars">AOAUEaoaue

variable name="OddChars" select="('Ä','Ö','Å','Ü','É','ä','ö','å','ü','é','ß')" variable name="RegChars" select="('Ae','Oe','AA','Ue','Ee','ae','oe','aa','ue','ee','SS')"

variable name="fr" select="('[Å-é]', 'Å', 'ß')" variable name="to_newChar" select="('Y', 'A', 'S')"

But none of them work

Thank you

2 Answers2

1

For XSLT-1.0 I'd make myself a mapping xml, which I called translationMapping.xml

<?xml version="1.0" encoding="UTF-8"?>
<translations>
    <translate OddChar="Ä" RegChar="Ae"/>
    <translate OddChar="ä" RegChar="ae"/>
    <translate OddChar="Ö" RegChar="Oe"/>
</translations>

Than you can use the following template, it will loop through text character by character and check if it finds the current character in the mapping and replace it if it finds a match (be aware, this might not perform very fast depending on the amount of text you give it):

<xsl:template name="translate">
    <xsl:param name="text"/>
    <xsl:variable name="char" select="substring($text,1,1)"/>
    <xsl:variable name="rest" select="substring($text,2)"/>
    <xsl:if test="$text!=''">
        <xsl:choose>
            <xsl:when test="document('translationMapping.xml')/*/translate[@OddChar=$char]">
                <xsl:value-of select="document('translationMapping.xml')/*/translate[@OddChar=$char]/@RegChar"/>
                <xsl:call-template name="translate">
                    <xsl:with-param name="text" select="$rest"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$char"/>
                <xsl:call-template name="translate">
                    <xsl:with-param name="text" select="$rest"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

You could call the template in a template that matches text():

<xsl:template match="text()">
    <xsl:call-template name="translate">
        <xsl:with-param name="text" select="."/>
    </xsl:call-template>
</xsl:template>

XSLT-2.0 has build in support for this kind of Operation with xsl:character-map which you can define like this:

<xsl:character-map name="char">
    <xsl:output-character character="Ä" string="Ae"/>
    <xsl:output-character character="Ö" string="oe"/>
    ...
</xsl:character-map>

The XSLT processor should than take care of replacing the characters for you.

Tobias Klevenz
  • 1,625
  • 11
  • 13
0

Let's to suppose that your source is:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<string>UÅ1atx-ß3Å</string>

and now, I think that you need is a recursive template that replace a character within a string until that character does not exist inside that initial string, so your code could be:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/string">
    <xsl:call-template name="replace">
        <xsl:with-param name="string" select="." />
        <xsl:with-param name="toReplace" select="'Å'" />
        <xsl:with-param name="replaced" select="'AA'" />
    </xsl:call-template>
</xsl:template>

<xsl:template name="replace">
    <xsl:param name="string" />
    <xsl:param name="toReplace" />
    <xsl:param name="replaced" />

    <xsl:variable name="aux">
        <xsl:value-of
            select="concat(substring-before($string, $toReplace), $replaced, substring-after($string, $toReplace))" />
    </xsl:variable>


    <xsl:variable name="aux2">
        <xsl:choose>
            <xsl:when test="contains($aux, $toReplace)">
                <xsl:call-template name="replace">
                    <xsl:with-param name="string" select="$aux" />
                    <xsl:with-param name="toReplace" select="$toReplace" />
                    <xsl:with-param name="replaced" select="$replaced" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$aux" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:value-of select="$aux2" />
</xsl:template>

and then your out is:

<?xml version="1.0" encoding="UTF-8"?>UAA1atx-ß3AA

I know that you need to replace more characters but with this you could do the rest.