Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中将文档作为参数传递给XSL翻译_Java_Xslt - Fatal编程技术网

在Java中将文档作为参数传递给XSL翻译

在Java中将文档作为参数传递给XSL翻译,java,xslt,Java,Xslt,我正在致力于将国际化添加到XSL中。我见过很多创建dictionary.xml文件并通过文档('dictionary.xml')将其加载到XSL的示例。我想做类似的事情,但我不想创建dictionary.xml文件并将其存储在磁盘上,我宁愿在服务器启动时从SQL构建它,并将文档对象保存在Java内存中。然后我想将dictionary文档作为参数传递给transformer,以便我的XSL翻译函数可以使用它。然而,它似乎不起作用 相关Java代码: Document dictionary = Tr

我正在致力于将国际化添加到XSL中。我见过很多创建dictionary.xml文件并通过文档('dictionary.xml')将其加载到XSL的示例。我想做类似的事情,但我不想创建dictionary.xml文件并将其存储在磁盘上,我宁愿在服务器启动时从SQL构建它,并将文档对象保存在Java内存中。然后我想将dictionary文档作为参数传递给transformer,以便我的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视为字符串而不是节点。有什么线索吗?

有变化吗

select="$dictionary


帮助?

使用
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));
公共类DocURIResolver实现URIResolver{
最终地图文件;
公共文档解析程序(最终地图文档){
本文件=文件;
}
公共源解析(最终字符串href,最终字符串基){
最终文档doc=documents.get(href);
返回(doc!=null)?新建DOMSource(doc):null;
}
}
像这样使用它:

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));
documentdictionary=TranslationDictionary.getDictionaryDocument();
Map docs=newhashmap();
“字典”,字典;
//transformer是您的javax.xml.transform.transformer
transformer.setURIResolver(新的DocURIResolver(docs));
并在样式表中按名称引用它:

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


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

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

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


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

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

dictionary.getDocumentElement();

那就行了!看起来saxon处理文档参数的方式中有一个bug,它需要某种尚未完成的初始化?我没有深入研究调试器。

我使用的是Saxon9作为XSLT,如果这有帮助的话。这有助于并指出这个问题是XSLT处理器特定的,因此属于“XSLT处理器”标记。@DannyCohn-有什么特别的原因吗?这似乎是一个不必要的额外的复杂性层。如果必须的话,我会的,但我不认为我正在做的事情足够复杂,需要一个URIResolver,所以我想先尝试一些不太黑客的东西这对我来说最有效。。。在XSLT中使用Transformer上的setParameter方法时似乎需要一个节点集,但是,我还没有弄清楚如何将文档转换为节点集。。。甚至XPath节点集(返回节点列表)也不起作用。URIResolver工作可靠,如果需要,名称可以硬编码。然而,这是一个丑陋的解决方案,只是不知道更好。java中的XSLT非常混乱。我到办公室后会尝试一下。我还将尝试以另一种方式构造DOM文档,以确认其构造正确。你说DOM不是最有效的树表示。你能推荐点别的吗?我当然愿意改变这一点。我尝试了另一种创建DOM文档的方法,然后注意到即使在XSL消息中根元素是“dictionary”,如果我将文档写入磁盘,它也是“dictionary”。一旦我改变了xpath,它就工作了。谢谢你在说什么?如果解析器中有一个bug,由于某种原因导致$dictionary被视为标量值而不是节点集,那么它就会确定问题的原因。事实上,他的行为是由saxon解析器中的一个bug引起的(正如我发现并随后发布的),而不是这个特定的bug。“确定了问题的原因”-并可能修复了它,我应该补充说,如果节点集调用强制将类型解释转换为正确的格式(如果类型解释是原因的话).