我正在尝试使用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 = ‘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:无法解析参数号$ lang.opdracht
答案 0 :(得分: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。
答案 1 :(得分: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目录选择任何您喜欢的名称,请记住它起着特殊的作用。)
可读性:
<!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 /路径时都会调用此实体解析器。
发生这种情况时,请检查路径是否以魔术前缀(您的特殊目录)开头,然后将此前缀转换为指向所需语言的人类可读路径。
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);
缺点很明显:您需要在XML / XSLT之外进行一些编码,并且XSLT样式表仅在超级特殊应用程序中使用时才是多语言的。
好处是在我的XSLT样式表中已经没有多余的标签了。