XSLT - 使用 key() 查找翻译字符串
XSLT - Translate strings using key() lookup
我正在尝试解决一个问题,我必须使用 xslt 翻译字符串。
我看到了这个:XSLT key() lookup
还有这个:
但我无法让它工作。我试图想出下面的最小示例,它显示了我面临的问题。
“真正的”xsl 是使用构建过程从代码片段组装而成的。这涉及到一些限制。
翻译查找 table 的内部结构始终是相同的,因为它们是从翻译工具以平面 xml 格式下载的 http://docs.translatehouse.org/projects/translate-toolkit/en/latest/formats/flatxml.html。我只能将它们包装到不同的父节点中,这是我尝试使用“lu”命名空间所做的。
所有语言的翻译 tables 必须存储在 xsl 中,因为具有不同翻译的不同代 xsl 可能彼此相邻存在。所以没有“sidecar”文件。
到现在我还拿不到工作钥匙。 xsltproc 的输出如下:
Setup Key - Start
German
xsltApplyOneTemplate: key was not compiled
Setup Key - End
de # skipped #
de # failed #
预期输出:
Setup Key - Start
German
Setup Key - End
de # skipped # Übersprungen
de # failed # Fehlgeschlagen
XML 文件只需要包含一个根元素。
很明显,我尝试根据目标语言定义密钥的方式是错误的,但我的 xsl 知识现在已经达到了极限。语言在转换过程中保持不变,因此所有翻译查找的键只需在开始时设置一次。
xsl 转换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:lu="http://www.my.domain.de/lookup"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vLanguageCode">
<!-- <xsl:value-of select="/root/@language"/> -->
<xsl:value-of select="'de'"/>
</xsl:variable>
<xsl:template match="/">
<xsl:call-template name="setupKey"/>
<xsl:call-template name="getLabel">
<xsl:with-param name="pKey" select="'skipped'"/>
</xsl:call-template>
<xsl:call-template name="getLabel">
<xsl:with-param name="pKey" select="'failed'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="setupKey">
<xsl:message>Setup Key - Start</xsl:message>
<xsl:choose>
<xsl:when test="$vLanguageCode='DE' or $vLanguageCode='de'">
<xsl:message>German</xsl:message>
<xsl:key name="kLanguageDict" match="/lu:de/root/str" use="@key"/>
</xsl:when>
<xsl:otherwise>
<xsl:message>English (default)</xsl:message>
<xsl:key name="kLanguageDict" match="/lu:en/root/str" use="@key"/>
</xsl:otherwise>
</xsl:choose>
<xsl:message>Setup Key - End</xsl:message>
</xsl:template>
<xsl:template name="getLabel">
<xsl:param name="pKey"/>
<xsl:variable name="vResult">
<xsl:value-of select="key('kLanguageDict', $pKey)/@str"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$vResult!=''">
<xsl:value-of select="$vResult"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pKey"/>
</xsl:otherwise>
</xsl:choose>
<xsl:message>
<xsl:value-of select="concat($vLanguageCode, ' # ', $pKey, ' # ', $vResult)"/>
</xsl:message>
</xsl:template>
<lu:de>
<root>
<str key="skipped">Übersprungen</str>
<str key="failed">Fehlgeschlagen</str>
</root>
</lu:de>
<lu:en>
<root>
<str key="skipped">Skipped</str>
<str key="failed">Failed</str>
</root>
</lu:en>
</xsl:stylesheet>
根据@michael.hor257k 的回答补充:
- 谢谢。我不知道。所以这意味着我不能根据语言有选择地定义一个键?
- 翻译系统最初在顶层有一个键和一个翻译 table,每种语言都有交错的条目。它使用双索引(语言+id)来查找值。
我正在尝试找到一个解决方案,我可以将翻译管理系统 (weblate) 返回的 xml 文件直接嵌入到 xsl 中,而无需修改它们。不幸的是,看起来我能得到的东西有限(只有默认节点和属性)。
这是原始工作翻译查找代码的核心:
<xsl:variable name="vLanguageDict" select="document('')/*/lu:strings"/>
<xsl:key name="kLanguageDict" match="lu:string" use="concat(@lang,@id)"/>
<xsl:template name="getLabel">
<xsl:param name="pKey"/>
<xsl:variable name="vResult">
<xsl:for-each select="$vLanguageDict">
<xsl:value-of select="key('kLanguageDict', concat($vLanguageCode,$pKey))/@value" />
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$vResult!=''">
<xsl:value-of select="$vResult"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pKey"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<lu:strings>
<lu:string lang="DE" id="skipped" value="Übersprungen"/>
<lu:string lang="EN" id="skipped" value="skipped"/>
<lu:string lang="DE" id="failed" value="Fehlgeschlagen"/>
<lu:string lang="EN" id="failed" value="failed"/>
</lu:strings>
您的 XSLT 样式表中有两个错误立即跳出:
xsl:key
元素只允许在顶层作为子元素
xsl:stylesheet
元素。
- 在 XSLT 1.0 中,键仅对当前文档起作用。如果要从样式表本身进行查找,则必须在调用
key()
函数之前将上下文更改为样式表文档。这里有两个例子:
恐怕没有可复制的例子就只能说这么多了。
---添加---
So this means that I can't selectively define a key depending on language?
您不能有条件地定义键 - 但您可以定义多个键,并且 select 根据指定的语言定义要使用的键。这是一个简化的例子:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dict="http://example.com/dict">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="de" match="dict:de/entry" use="@key" />
<xsl:key name="en" match="dict:en/entry" use="@key" />
<xsl:param name="input">skipped</xsl:param>
<xsl:param name="lang">de</xsl:param>
<xsl:template match="/">
<xsl:value-of select="$lang"/>
<xsl:text> # </xsl:text>
<xsl:value-of select="$input"/>
<xsl:text> = </xsl:text>
<!-- switch context to stylesheet in order to use key -->
<xsl:for-each select="document('')">
<xsl:value-of select="key($lang, $input)"/>
</xsl:for-each>
</xsl:template>
<dict:de>
<entry key="skipped">Übersprungen</entry>
<entry key="failed">Fehlgeschlagen</entry>
</dict:de>
<dict:en>
<entry key="skipped">Skipped</entry>
<entry key="failed">Failed</entry>
</dict:en>
</xsl:stylesheet>
应用于任何 XML 输入,这将 return:
结果
de : skipped = Übersprungen
我正在尝试解决一个问题,我必须使用 xslt 翻译字符串。
我看到了这个:XSLT key() lookup
还有这个:
但我无法让它工作。我试图想出下面的最小示例,它显示了我面临的问题。 “真正的”xsl 是使用构建过程从代码片段组装而成的。这涉及到一些限制。
翻译查找 table 的内部结构始终是相同的,因为它们是从翻译工具以平面 xml 格式下载的 http://docs.translatehouse.org/projects/translate-toolkit/en/latest/formats/flatxml.html。我只能将它们包装到不同的父节点中,这是我尝试使用“lu”命名空间所做的。 所有语言的翻译 tables 必须存储在 xsl 中,因为具有不同翻译的不同代 xsl 可能彼此相邻存在。所以没有“sidecar”文件。
到现在我还拿不到工作钥匙。 xsltproc 的输出如下:
Setup Key - Start
German
xsltApplyOneTemplate: key was not compiled
Setup Key - End
de # skipped #
de # failed #
预期输出:
Setup Key - Start
German
Setup Key - End
de # skipped # Übersprungen
de # failed # Fehlgeschlagen
XML 文件只需要包含一个根元素。
很明显,我尝试根据目标语言定义密钥的方式是错误的,但我的 xsl 知识现在已经达到了极限。语言在转换过程中保持不变,因此所有翻译查找的键只需在开始时设置一次。
xsl 转换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:lu="http://www.my.domain.de/lookup"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vLanguageCode">
<!-- <xsl:value-of select="/root/@language"/> -->
<xsl:value-of select="'de'"/>
</xsl:variable>
<xsl:template match="/">
<xsl:call-template name="setupKey"/>
<xsl:call-template name="getLabel">
<xsl:with-param name="pKey" select="'skipped'"/>
</xsl:call-template>
<xsl:call-template name="getLabel">
<xsl:with-param name="pKey" select="'failed'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="setupKey">
<xsl:message>Setup Key - Start</xsl:message>
<xsl:choose>
<xsl:when test="$vLanguageCode='DE' or $vLanguageCode='de'">
<xsl:message>German</xsl:message>
<xsl:key name="kLanguageDict" match="/lu:de/root/str" use="@key"/>
</xsl:when>
<xsl:otherwise>
<xsl:message>English (default)</xsl:message>
<xsl:key name="kLanguageDict" match="/lu:en/root/str" use="@key"/>
</xsl:otherwise>
</xsl:choose>
<xsl:message>Setup Key - End</xsl:message>
</xsl:template>
<xsl:template name="getLabel">
<xsl:param name="pKey"/>
<xsl:variable name="vResult">
<xsl:value-of select="key('kLanguageDict', $pKey)/@str"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$vResult!=''">
<xsl:value-of select="$vResult"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pKey"/>
</xsl:otherwise>
</xsl:choose>
<xsl:message>
<xsl:value-of select="concat($vLanguageCode, ' # ', $pKey, ' # ', $vResult)"/>
</xsl:message>
</xsl:template>
<lu:de>
<root>
<str key="skipped">Übersprungen</str>
<str key="failed">Fehlgeschlagen</str>
</root>
</lu:de>
<lu:en>
<root>
<str key="skipped">Skipped</str>
<str key="failed">Failed</str>
</root>
</lu:en>
</xsl:stylesheet>
根据@michael.hor257k 的回答补充:
- 谢谢。我不知道。所以这意味着我不能根据语言有选择地定义一个键?
- 翻译系统最初在顶层有一个键和一个翻译 table,每种语言都有交错的条目。它使用双索引(语言+id)来查找值。
我正在尝试找到一个解决方案,我可以将翻译管理系统 (weblate) 返回的 xml 文件直接嵌入到 xsl 中,而无需修改它们。不幸的是,看起来我能得到的东西有限(只有默认节点和属性)。
这是原始工作翻译查找代码的核心:
<xsl:variable name="vLanguageDict" select="document('')/*/lu:strings"/>
<xsl:key name="kLanguageDict" match="lu:string" use="concat(@lang,@id)"/>
<xsl:template name="getLabel">
<xsl:param name="pKey"/>
<xsl:variable name="vResult">
<xsl:for-each select="$vLanguageDict">
<xsl:value-of select="key('kLanguageDict', concat($vLanguageCode,$pKey))/@value" />
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$vResult!=''">
<xsl:value-of select="$vResult"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pKey"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<lu:strings>
<lu:string lang="DE" id="skipped" value="Übersprungen"/>
<lu:string lang="EN" id="skipped" value="skipped"/>
<lu:string lang="DE" id="failed" value="Fehlgeschlagen"/>
<lu:string lang="EN" id="failed" value="failed"/>
</lu:strings>
您的 XSLT 样式表中有两个错误立即跳出:
xsl:key
元素只允许在顶层作为子元素xsl:stylesheet
元素。- 在 XSLT 1.0 中,键仅对当前文档起作用。如果要从样式表本身进行查找,则必须在调用
key()
函数之前将上下文更改为样式表文档。这里有两个例子:
恐怕没有可复制的例子就只能说这么多了。
---添加---
So this means that I can't selectively define a key depending on language?
您不能有条件地定义键 - 但您可以定义多个键,并且 select 根据指定的语言定义要使用的键。这是一个简化的例子:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dict="http://example.com/dict">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="de" match="dict:de/entry" use="@key" />
<xsl:key name="en" match="dict:en/entry" use="@key" />
<xsl:param name="input">skipped</xsl:param>
<xsl:param name="lang">de</xsl:param>
<xsl:template match="/">
<xsl:value-of select="$lang"/>
<xsl:text> # </xsl:text>
<xsl:value-of select="$input"/>
<xsl:text> = </xsl:text>
<!-- switch context to stylesheet in order to use key -->
<xsl:for-each select="document('')">
<xsl:value-of select="key($lang, $input)"/>
</xsl:for-each>
</xsl:template>
<dict:de>
<entry key="skipped">Übersprungen</entry>
<entry key="failed">Fehlgeschlagen</entry>
</dict:de>
<dict:en>
<entry key="skipped">Skipped</entry>
<entry key="failed">Failed</entry>
</dict:en>
</xsl:stylesheet>
应用于任何 XML 输入,这将 return:
结果
de : skipped = Übersprungen