如果您在自己的应用程序中执行转换,则可以使用另一种方法。一种需要一些编码但使您的样式表不那么混乱的方法。
样式表:
<?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.