【发布时间】:2018-05-19 00:38:01
【问题描述】:
我正在使用 XSLT 并将结果写入 Java 中的多个输出,如以下链接所述: link1, link2。
在写入文件时,一切正常,但现在我想将输出 XML 存储为 Document 对象或某种 InputStream/String - 除了驱动器上的文件之外的任何内容。使用 Transformer 将文档写入到文件,然后将它们读取到对象(文档、字符串等) 不是一种选择。
我的问题是:我应该在我的 xslt 映射和 java 代码中进行哪些更改才能将输出作为对象而不是驱动器上的文件。 (我想出的唯一解决方案是在这个 XML 上使用两个 XSLT,但这不是优雅的方式)
我的 Java 代码类似于上面链接中的答案。 我正在使用 XSLT 2.0 并使用以下方式进行转换:
transformer.transform(xmlText, new DOMResult());
我也加了
<xsl:result-document href="{concat($jobName, '_assets.xml')}">
<xsl:apply-templates select="GetMetadata/Metadata" mode="assets"/>
</xsl:result-document>
<xsl:result-document href="{concat($jobName, '_flows.xml')}">
<xsl:apply-templates select="GetMetadata/Metadata" mode="flows"/>
</xsl:result-document>
到我的 xsl 地图 [写入文件工作正常]
稍后
正确的实现:(谢谢迈克尔)
public void multipleXMLExtractor(Document inputDom, String xsltPath) throws TransformerException, UnsupportedEncodingException {
Source xmlInput = new DOMSource(inputDom);
Source xsltMap = new StreamSource(new File(xsltPath));
final Map<String, StreamResult> resultsMap = new HashMap<String, StreamResult>();
resultsMap.put("output1", new StreamResult(new ByteArrayOutputStream()));
resultsMap.put("output2", new StreamResult(new ByteArrayOutputStream()));
TransformerFactory tFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", XMLviaXSLTransformer.class.getClassLoader());
Transformer transformer = tFactory.newTransformer(xsltMap);
((net.sf.saxon.jaxp.TransformerImpl) transformer).getUnderlyingController().setOutputURIResolver(new OutputURIResolver() {
@Override
public OutputURIResolver newInstance() {
return this;
}
@Override
public Result resolve(String s, String s1) throws TransformerException {
return resultsMap.get(s);
}
@Override
public void close(Result result) throws TransformerException {
}
});
StreamResult standardResult = new StreamResult(new ByteArrayOutputStream());
transformer.transform(xmlInput, standardResult);
for (Map.Entry<String, StreamResult> stringStreamResultEntry : resultsMap.entrySet()) {
System.out.println(stringStreamResultEntry.getKey() + ": " + ((ByteArrayOutputStream) stringStreamResultEntry.getValue().getOutputStream()).toString("UTF-8"));
}
}
【问题讨论】:
-
请准确告诉我们您使用的是哪个版本的 XSLT 2 处理器。如果它是 Saxon 9 并且您使用 JAXP API 来运行 XSLT 2,那么您可能希望切换 Saxon 9 API 以访问配置(尽管我认为您也可以通过 JAXP 和 Saxon 特定代码来做到这一点)和然后设置saxonica.com/html/documentation/javadoc/net/sf/saxon/…根据需要处理结果文档。
-
"net.sf.saxon.TransformerFactoryImpl" 我正在使用处理器:Saxon - HE 9.8.0-3 并导入 javax.xml ...我仍然不知道如何实现不是输出到文件,而是输出到某个流
-
@MartinHonnen 由于线程安全问题,将
OutputURIResolver设置为Controller级别而不是Configuration可能更安全。