Converting language to language / country with XSL
I need to figure out how to best convert the language strings to a human-readable name. I could write a big one <xsl:choose>
and just add a condition for each of the locales I want to convert, but I think that's probably a more efficient or smarter way.
My input looks like this:
<content name="locale" value="en_US" />
<content name="locale" value="ja_JP" />
And the corresponding output might look like this:
<content name="language" value="English" />
<content name="language" value="Japanese" />
In my case, I am not interested in the country now, only in the language. I also don't need to check all possible locales, only 10 or so at present, but there may be more in the future, so I'm looking for the least rigid way to handle the conversion.
source to share
You can save the mapping in another XML file and access it using a function document()
from your stylesheet. Assuming you have a mapping file similar to that suggested by Chris McCall in his answer, you can do it like this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="mapping"
select="document('mapping.xml')"/>
<xsl:template match="content[@name='locale']">
<xsl:variable name="locale" select="@value"/>
<content name="language">
<xsl:attribute name="value">
<xsl:value-of
select="$mapping//content-map[@locale=$locale]/@language"/>
</xsl:attribute>
</content>
</xsl:template>
</xsl:stylesheet>
If you want a really compact solution, you can even enable rendering inside the stylesheet itself. Since XSLT processors must ignore any elements not in the XSLT namespace in the element xsl:stylesheet
, you can include mapping there. You can access the XSLT document itself as document('')
.
Thus, a stand-alone style sheet with display might look like this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:map="https://stackoverflow.com/questions/1428947#"
exclude-result-prefixes="map"
>
<map:mapping>
<map:content-map locale="en_US" language="English"/>
<map:content-map locale="ja_JP" language="Japanese"/>
</map:mapping>
<xsl:variable name="mapping"
select="document('')//map:mapping"/>
<xsl:template match="content[@name='locale']">
<xsl:variable name="locale" select="@value"/>
<content name="language">
<xsl:attribute name="value">
<xsl:value-of
select="$mapping//map:content-map[@locale=$locale]/@language"/>
</xsl:attribute>
</content>
</xsl:template>
</xsl:stylesheet>
source to share