将文档作为参数传递给Java中的XSL Translation

时间:2012-01-16 23:02:48

标签: java xslt

我正在为我的XSL添加国际化。我已经看到很多创建dictionary.xml文件并通过文档('dictionary.xml')将其加载到我的XSL中的示例。我想做类似的事情,但我不想在磁盘上创建和存储dictionary.xml文件,我宁愿在服务器启动时从SQL构建它,并将Document对象保存在Java内存中。我想将字典文档作为参数传递给变换器,以便我的XSL转换函数可以使用它。但是,它似乎没有起作用。

相关的Java代码:

Document dictionary = TranslationDictionary.getDictionaryDocument();
transformer.setParameter("dictionary", dictionary);

字典文档内容:

<dictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <translatedString dictionaryId="BASIC_DETAILS">
        <language id="es" value="Detalles B&#225;sicos"/>
    </translatedString >
    <translatedString dictionaryId="VEHICLE_INFORMATION">
        <language id="es" value="Informaci&#243;n del Veh&#237;culo"/>
    </translatedString >
    <translatedString dictionaryId="STRUCTURE">
        <language id="es" value="Estructura"/>
    </translatedString >
    <translatedString dictionaryId="DRIVER_INFORMATION">
        <language id="es" value="Informaci&#243;n del Conductor"/>
    </translatedString >
    <translatedString dictionaryId="MAINTENANCE_AND_FEUL">
        <language id="es" value="Mantenimiento &amp; Combustible"/>
    </translatedString >
    <translatedString dictionaryId="PURCHASING">
        <language id="es" value="Compra"/>
    </translatedString >
</dictionary>

XSL文件:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://www.test.com">
    <xsl:param name="dictionary"/>
    <xsl:param name="language" select="'es'"/>


<xsl:template match="/">
<xsl:message>
    <xsl:copy-of select="$dictionary/dictionary/translatedString[@dictionaryId='BASIC_DETAILS']/language[@id='es']/@value"/>
</xsl:message>

</xsl:template>

但我一无所获。我试过只做一个$ document / document的副本来确认我没有xpath问题,而不是那个,因为这给了我一份完整的文档。就像XSL将$ dictionary视为字符串而不是节点一样。有线索吗?

4 个答案:

答案 0 :(得分:8)

使用URIResolver代替参数。首先,像这样创建解析器:

public class DocURIResolver implements URIResolver {

    final Map<String, Document> documents;

    public DocURIResolver(final Map<String, Document> documents) {
        this.documents = documents;
    }

    public Source resolve(final String href, final String base) {
        final Document doc = documents.get(href);
        return (doc != null) ? new DOMSource(doc) : null;
    }
}

像这样使用:

Document dictionary = TranslationDictionary.getDictionaryDocument();
Map<String, Document> docs = new HashMap<String, Document>();
docs.put("dictionary", dictionary);
// transformer is your javax.xml.transform.Transformer
transformer.setURIResolver(new DocURIResolver(docs));

并按名称在样式表中引用它:

<xsl:variable name="dict" select="document('dictionary')"/>

当然,这只是一个玩具的例子。您可以根据需要使URIResolver功能齐全。

答案 1 :(得分:4)

好的,我制作了代码的骨架副本。这听起来很奇怪,但是在java代码中创建字典文档之后,在将其设置为变换器的参数之前,只需调用方法:

dictionary.getDocumentElement();

然后它的作品!看起来像saxon处理文档参数的方式中的一个错误,它需要某种初始化而未完成?我没有深入研究调试器。

答案 2 :(得分:3)

将DOM Document节点作为参数传递给Saxon转换应该有效(从长远来看,DOM不是最有效的树表示,但它应该工作)。所以应该传递包装DOM Document的DOMSource。我通常从做xsl:copy-of select =“$ doc”开始,你似乎已经这样做并确认该值正确传递。如果您没有得到任何响应文档中的XPath选择的内容,这通常意味着XPath表达式是错误的。最常见的原因是忘记了根(文档)节点,忘记了命名空间。但是我担心在你向我们展示的代码中没有证据表明存在这样的错误 - 假设DOM反映了你在帖子中显示的XML。

您的帖子建议您以编程方式构建DOM文档。您可能已经创建了Saxon由于某种原因无法处理的DOM:DOM接口不是很强大,当人们使用未经Saxon测试的DOM实现时,有时会遇到困难。

您还可以通过从命令行运行样式表来测试样式表 - 您可以使用+ dictionary = dict.xml提供$ dictionary参数的值(前导'+'使其被识别为a的名称需要解析的文件。)

答案 3 :(得分:-2)

更改

select="$dictionary

select="node-set($dictionary)

帮助?