Saxon XSLT 转换后 Apache FOP 转换缓慢
Slow Apache FOP Transformation after Saxon XSLT Transformation
在 Java 应用程序中,我使用 Saxon HE (9.9) 进行 XML-FO 转换。之后我使用 Apache FOP (2.3) 创建 PDF 文件。与随后两个转换的 cli 上的执行时间相比,FOP 转换很慢(大约 12 秒对仅 FOP 部分的 2 秒)。
// XML->FO
Processor proc = new Processor(false);
ExtensionFunction highlightingImage = new OverlayImage();
proc.registerExtensionFunction(highlightingImage);
ExtensionFunction mergeImage = new PlanForLandRegisterMainPageImage();
proc.registerExtensionFunction(mergeImage);
ExtensionFunction rolImage = new RestrictionOnLandownershipImage();
proc.registerExtensionFunction(rolImage);
ExtensionFunction fixImage = new FixImage();
proc.registerExtensionFunction(fixImage);
ExtensionFunction decodeUrl = new URLDecoder();
proc.registerExtensionFunction(decodeUrl);
XsltCompiler comp = proc.newXsltCompiler();
XsltExecutable exp = comp.compile(new StreamSource(new File(xsltFileName)));
XdmNode source = proc.newDocumentBuilder().build(new StreamSource(new File(xmlFileName)));
Serializer outFo = proc.newSerializer(foFile);
XsltTransformer trans = exp.load();
trans.setInitialContextNode(source);
trans.setDestination(outFo);
trans.transform();
// FO->PDF
FopFactory fopFactory = FopFactory.newInstance(fopxconfFile);
OutputStream outPdf = new BufferedOutputStream(new FileOutputStream(pdfFile));
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, outPdf);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
Source src = new StreamSource(foFile);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
到目前为止,我非常确定它不依赖于生成的 FO 文件的某些文件处理问题。如果我转换一个与 Saxon 生成的文件完全不同的 FO 文件,FO 转换甚至会很慢。即使不执行 XML-FO 转换时控制台中的输出也不同:
Dec 25, 2018 1:54:47 AM org.apache.fop.apps.FOUserAgent processEvent
INFO: Rendered page #1.
Dec 25, 2018 1:54:47 AM org.apache.fop.apps.FOUserAgent processEvent
INFO: Rendered page #2.
之前执行XML-FO转换时不会在控制台打印此输出。
XML-FO 转换步骤中是否有任何必须关闭的内容?
这种行为的原因是什么?
我认为如果您使用 Saxon 自己的 API 来设置一个 Processor
和您的扩展函数,然后想将转换 XSL-FO 结果直接通过管道传输到 Apache FOP 处理器,您可以直接设置 SAXDestination
:
XsltTransformer trans = exp.load();
trans.setInitialContextNode(source);
FopFactory fopFactory = FopFactory.newInstance(fopxconfFile);
OutputStream outPdf = new BufferedOutputStream(new FileOutputStream(pdfFile));
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, outPdf);
trans.setDestination(new SAXDestination(fop.getDefaultHandler()));
trans.transform();
outPdf.close();
参见http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop/examples/embedding/java/embedding/ExampleXML2PDF.java?view=markup together with Saxon's http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XsltTransformer.html#setDestination-net.sf.saxon.s9api.Destination-。
在 Java 应用程序中,我使用 Saxon HE (9.9) 进行 XML-FO 转换。之后我使用 Apache FOP (2.3) 创建 PDF 文件。与随后两个转换的 cli 上的执行时间相比,FOP 转换很慢(大约 12 秒对仅 FOP 部分的 2 秒)。
// XML->FO
Processor proc = new Processor(false);
ExtensionFunction highlightingImage = new OverlayImage();
proc.registerExtensionFunction(highlightingImage);
ExtensionFunction mergeImage = new PlanForLandRegisterMainPageImage();
proc.registerExtensionFunction(mergeImage);
ExtensionFunction rolImage = new RestrictionOnLandownershipImage();
proc.registerExtensionFunction(rolImage);
ExtensionFunction fixImage = new FixImage();
proc.registerExtensionFunction(fixImage);
ExtensionFunction decodeUrl = new URLDecoder();
proc.registerExtensionFunction(decodeUrl);
XsltCompiler comp = proc.newXsltCompiler();
XsltExecutable exp = comp.compile(new StreamSource(new File(xsltFileName)));
XdmNode source = proc.newDocumentBuilder().build(new StreamSource(new File(xmlFileName)));
Serializer outFo = proc.newSerializer(foFile);
XsltTransformer trans = exp.load();
trans.setInitialContextNode(source);
trans.setDestination(outFo);
trans.transform();
// FO->PDF
FopFactory fopFactory = FopFactory.newInstance(fopxconfFile);
OutputStream outPdf = new BufferedOutputStream(new FileOutputStream(pdfFile));
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, outPdf);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
Source src = new StreamSource(foFile);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
到目前为止,我非常确定它不依赖于生成的 FO 文件的某些文件处理问题。如果我转换一个与 Saxon 生成的文件完全不同的 FO 文件,FO 转换甚至会很慢。即使不执行 XML-FO 转换时控制台中的输出也不同:
Dec 25, 2018 1:54:47 AM org.apache.fop.apps.FOUserAgent processEvent
INFO: Rendered page #1.
Dec 25, 2018 1:54:47 AM org.apache.fop.apps.FOUserAgent processEvent
INFO: Rendered page #2.
之前执行XML-FO转换时不会在控制台打印此输出。
XML-FO 转换步骤中是否有任何必须关闭的内容?
这种行为的原因是什么?
我认为如果您使用 Saxon 自己的 API 来设置一个 Processor
和您的扩展函数,然后想将转换 XSL-FO 结果直接通过管道传输到 Apache FOP 处理器,您可以直接设置 SAXDestination
:
XsltTransformer trans = exp.load();
trans.setInitialContextNode(source);
FopFactory fopFactory = FopFactory.newInstance(fopxconfFile);
OutputStream outPdf = new BufferedOutputStream(new FileOutputStream(pdfFile));
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, outPdf);
trans.setDestination(new SAXDestination(fop.getDefaultHandler()));
trans.transform();
outPdf.close();
参见http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop/examples/embedding/java/embedding/ExampleXML2PDF.java?view=markup together with Saxon's http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XsltTransformer.html#setDestination-net.sf.saxon.s9api.Destination-。