Given the following XML:
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="form.xsl"?>
<Document>
<Translations>
<Translation name="Resource">Invariant Resource</Translation>
<Translation name="Resource" lang="en">English Resource</Translation>
<Translation name="Resource" lang="en-CA">Canadian English Resource</Translation>
<Translation name="Resource" lang="en-GB">British English Resource</Translation>
<Translation name="Message">Invariant Message</Translation>
<Translation name="Message" lang="en">English Message</Translation>
<Translation name="Message" lang="en-CA">Canadian English Message</Translation>
<Translation name="Message" lang="en-AU">Australian English Message</Translation>
</Translations>
</Document>
I need to select a set of translation elements so that the set contains unique values for the attribute "name" and "best match" for a given language ("en-US", "es-MX", fr ', etc.). When I say the best match, I would like to first find an element with a complete matching language, and then look for a match based only on the first two characters, and then look for an element without a lang pointer.
For example, if I go to the "en-CA" locale when converting the above data, I would like to get the following two elements:
<Translation name="Resource" lang="en-CA">Canadian English Resource</Translation>
<Translation name="Message" lang="en-CA">Canadian English Message</Translation>
But if I go to 'en-GB', I would like to get:
<Translation name="Resource" lang="en-GB">British English Resource</Translation>
<Translation name="Message" lang="en">English Message</Translation>
And finally, if I pass in a value such as "es" or "es-MX", I would expect to get:
<Translation name="Resource">Invariant Resource</Translation>
<Translation name="Message">Invariant Message</Translation>
XSLT, , -, . , ( , , ..).
:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:key match="Translation" name="TranslationName" use="concat(@name,':',@lang)"/>
<xsl:template match="/">
<xsl:param name="locale"/>
<xsl:for-each select="Document/Translations/Translation[@lang=$locale or @lang=substring($locale,1,2) or not(@lang)]">
<xsl:choose>
<xsl:when test="@lang=$locale and count(key('TranslationName', concat(@name,':',$locale)))=1">
<xsl:element name="p">
<xsl:value-of select="."/>
</xsl:element>
</xsl:when>
<xsl:when test="@lang=substring($locale,1,2) and count(key('TranslationName', concat(@name,':',$locale)))=0">
<xsl:element name="p">
<xsl:value-of select="."/>
</xsl:element>
</xsl:when>
<xsl:when test="not(@lang) and count(key('TranslationName', concat(@name,':',$locale))|key('TranslationName', concat(@name,':',substring($locale,1,2))))=0">
<xsl:element name="p">
<xsl:value-of select="."/>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
, , , , , // -.
!