Reputation: 8481
I need to figure out the best way to convert locale strings to a human-friendly name. I could write a large <xsl:choose>
and just add a condition for each of the locales I want to convert, but I think there is probably a more efficient or clever way.
My input looks like this:
<content name="locale" value="en_US" />
<content name="locale" value="ja_JP" />
And corresponding output might look like this:
<content name="language" value="English" />
<content name="language" value="Japanese" />
In my case I don't care about the country right now, only the language. I also don't have to check all possible locales, only 10 or so currently, but there may be more in the future which is why I'm looking for the least rigid way of processing the conversion.
Upvotes: 2
Views: 2609
Reputation: 10188
You can store the mapping in another XML file and access it using the document()
function from your stylesheet. Assuming you have a mapping file like the one suggested by Chris McCall in his answer, you could 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 include the mapping within the stylesheet itself. Since XSLT processors are required to ignore any elements not from the XSLT namespace within the xsl:stylesheet
element, you can include the mapping there. You can access the XSLT document itself as document('')
.
So the self-contained stylesheet with a mapping could 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>
Upvotes: 2
Reputation: 43560
There's probably a better way, but you could have the nicely formatted country lookups in a separate XML document and then refer and zip that information into your output.
That would at least keep the big choose statement at bay, and give you future expansion options.
Upvotes: 0
Reputation: 10397
Interesting question!
How about an intermediate XML mapping file?:
<content-maps>
<content-map locale="en_US" language="English"/>
<content-map locale="ja_JP" language="Japanese"/>
</content-maps>
Use XSL to create your <xsl:choose>
block from that and run the results over your input file.
Upvotes: 1