次の 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>
「name」属性の一意の値と、特定のロケール (「en-US」、「es-MX」、「fr」、等。)。ベスト マッチと言うと、最初に完全に一致するロケールを持つ要素を探し、次に最初の 2 文字だけに基づいて一致するものを探し、次に言語が指定されていない要素を探します。
たとえば、上記のデータを変換するときに「en-CA」のロケールを渡す場合、次の 2 つの要素を取得したいと考えています。
<Translation name="Resource" lang="en-CA">Canadian English Resource</Translation>
<Translation name="Message" lang="en-CA">Canadian English Message</Translation>
しかし、「en-GB」を渡すと、次のようになります。
<Translation name="Resource" lang="en-GB">British English Resource</Translation>
<Translation name="Message" lang="en">English Message</Translation>
最後に、「es」や「es-MX」などの値を渡すと、次の結果が得られると予想されます。
<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="/">
<!-- locale parameter for translation -->
<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>
質問を投稿するのはこれが初めてなので、何か追加/編集/削除する必要がある場合はお知らせください。
ありがとう!