使用 Saxon9HE API 在 Java 应用程序中使用 XSLT 转换多个输入 XML 文档

Transform multiple input XML documents with XSLT in a Java application using the Saxon9HE API

如何在 Java 应用程序中使用 Saxon9HE 处理器通过单个 XSL 转换脚本转换多个 XML 输入文档对象?

我找到了一种使用 XSLT 脚本从文件系统转换多个 XML 输入文件的方法 here,但我不知道如何传递多个加载的 XML 文档反对使用 Saxon9HE API 的 Java 应用程序。对于单个 XML 文档,我的代码如下所示并且有效:

    Processor proc = new Processor(false);

    XsltCompiler comp = proc.newXsltCompiler();

    try {
        XsltExecutable exp = comp.compile(new StreamSource(stylesheetFile));

        XdmNode source = proc.newDocumentBuilder().build(new DOMSource(inputXML));          
        Serializer out = proc.newSerializer();

        out.setOutputProperty(Serializer.Property.METHOD, "xml");
        out.setOutputProperty(Serializer.Property.INDENT, "yes");
        out.setOutputFile(new File(outputFilename));

        XsltTransformer trans = exp.load();

        trans.setInitialContextNode(source);
        trans.setDestination(out);
        trans.transform();
    } catch (SaxonApiException e) {
        e.printStackTrace();
    }

第一点:尽可能避免DOM。使用 Saxon 时,最好让 Saxon 构建文档树;这将更有效率。如果你真的需要使用外部树模型,XOM 和 JDOM2 比 DOM.

效率高得多

如果您确实想提供 DOM 作为输入,您有两种选择:可以将其复制到 Saxon 树,或者将其包装为 Saxon 树。在第一种情况下使用 DocumentBuilder.build(),在第二种情况下使用 DocumentBuilder.wrap()。使用 build() 会给你更高的初始成本,但转换本身会更快。

如果要将预建树传递到转换中,请使用 <xsl:param name="x" as="document-node()"/> 声明参数,然后使用 transformer.setParameter(new QName('x'), doc) 调用转换,其中 doc 是 XdmNode 的实例。您必须使用 DocumentBuilder 自己构建 XdmNode。

(或者,如果您想使用 doc() 或 document() 函数访问样式表中的文档,您可以发明一个 URI 命名方案并在 URIResolver 中实现它。当 doc('my:uri') 被调用,你的 URIResolver 被通知,它应该用一个 Source 对象响应。如果你已经有一个 XdmNode 方便,那么你可以 return XdmNode.asSource() to return this document树作为你的 URIResolver 的结果。)