6

我正在尝试使用 xml/xsl 制作不同语言的页面。我只想拥有一个 xml 和一个 xsl。在我的页面 Url 上,我有一个参数 pLanguage,我想我可以用它来查看我是否选择了英语或荷兰语。

我试过这段代码,但我不知道我是怎么把它放在一起的:

首先,我对所有需要翻译的单词进行变量处理,如下所示:

<xsl:variable name="lang.pageTitle" select="'This is the title in English'"/>

要在模板中获取 pageTitle,我现在可以使用

<xsl:value-of select="$lang.pageTitle"/>

我想通过使用 if-else 语句来测试我选择的语言是 EN 还是 NL 来替换上面的第一行代码,如下所示:

<xsl:choose>
      <xsl:when test="$choosenLanguage &#61; ‘NL’">
        <xsl:variable name="lang.pageTitle" select="Titel in het nederlands'"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="lang.pageTitle" select="'This is the title in English'"/>
      </xsl:otherwise>
    </xsl:choose>

但我收到错误:java.lang.IllegalArgumentException: can't parse argument number $lang.opdracht

4

2 回答 2

3

这是一个完整的示例,如何以通用方式完成此操作

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pLang" select="'nl'"/>

 <my:texts>
  <pageTitle lang="en">This is the title in English</pageTitle>
  <pageTitle lang="nl">Titel in het nederlands</pageTitle>
 </my:texts>

 <xsl:variable name="vTexts" select="document('')/*/my:texts"/>

 <xsl:template match="/">
     <html>
      <title>
        <xsl:value-of select="$vTexts/pageTitle[@lang = $pLang]"/>
      </title>
     </html>
 </xsl:template>
</xsl:stylesheet>

当将此转换应用于任何 XML 文档(未使用)时,将产生所需的正确结果(标题是根据全局/外部参数$pLang生成的):

<html>
   <title>Titel in het nederlands</title>
</html>

请注意

建议将所有字符串保存在与 XSLT 样式表文件分开的 XML 文档中。这允许在不更改 XSLT 代码的情况下修改/添加/删除字符串。

要从另一个 XML 文档访问字符串,代码几乎保持不变,唯一的区别是document()函数的参数现在是字符串 XML 文档的 URI。

于 2012-08-23T12:27:50.547 回答
1

如果您在自己的应用程序中执行转换,则可以使用另一种方法。一种需要一些编码但使您的样式表不那么混乱的方法。

样式表:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stylesheet SYSTEM "i18n/humanreadable.ent">
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"...>
    &text1; &text2;

(您可以为 i18n 目录选择任何您喜欢的名称,请记住它起着特殊的作用。)

人类可读的.ent:

<!ENTITY text1 "Hello">
<!ENTITY text2 "world!">

到目前为止,这仍然是一个很好的旧且有效的 XSLT。但是,虽然它使样式表更具可读性,但它并没有为您提供非常需要的多语言支持。为此,您需要进行一些编码。

自定义用于解析样式表文件的文档构建器;为其分配一个实体解析器

Source getStylesheetSource(String stylesheetFilename, EntityResolver entityResolver) throws ... {
    DocumentBuilder docBuilder = getDomFactory().newDocumentBuilder();
    docBuilder.setEntityResolver(entityResolver);
    Document stylesheet = docBuilder.parse(new FileInputStream(new File(stylesheetFilename)));
    return new DOMSource(stylesheet);
}

当您的样式表被解析为文档时,每次遇到相对 URL/路径时都会调用此实体解析器。
发生这种情况时,检查路径是否以您的魔术前缀(您的特殊目录)开头,并将此前缀转换为指向所需语言的 humanreadable.ent 的路径。

final String targetLanguage = figureOutDesiredLanguage(...);
EntityResolver entityResolver = new EntityResolver() {
        @Override
        public InputSource resolveEntity(String publicId, String systemId) throws IOException {
            if (pointsToMySpecialFolder(systemId)) {
                String lang = targetLanguage;
                String i18n = insertLangIntoThePath(systemId, lang);
                return new InputSource(new FileInputStream(new File(i18n)));
            }
            return null;
        }
};

Source stylesheet = getStylesheetSource("stylesheet.xslt", entityResolver);
Result result = new SAXResult(...);
Transformer transformer = transformerFactory.newTransformer(stylesheet);
transformer.transform(new DOMSource(inputXml), result);

The drawbacks are obvious: you need to do some coding outside of XML/XSLT, and your XSLT stylesheet is multi-lingual only when used within your super-special application.

The benefit is no extra tag soup in my (already rather dense) XSLT stylesheets.

于 2020-03-22T22:39:08.157 回答