我正在尝试使用Java
文档更改XML
将PDF
呈现为XSL-FO
的应用程序。应用程序从文件加载XSL-FO
文档,然后用于进行转换。以下是来源的相关部分:
protected void renderXML(String xmlPath, HttpServletResponse response)
throws FOPException, TransformerException, IOException {
//Setup sources
Source xmlSrc = convertString2Source(xmlPath+".tmp.xml");
Source xsltSrc = convertString2Source(xmlPath+".xsl");
//Setup the XSL transformation
Transformer transformer = transFactory.newTransformer(xsltSrc);
transformer.setURIResolver(this.uriResolver);
//Start transformation and rendering process
render(xmlSrc, transformer, response);
}
protected Source convertString2Source(String param) {
Source src;
try {
src = uriResolver.resolve(param, null);
} catch (TransformerException e) {
src = null;
}
if (src == null) {
src = new StreamSource(new File(param));
}
return src;
}
以下是我用于测试的示例XSL-FO
文档:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- Page master -->
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm">
<fo:region-body region-name="body" margin="0mm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="A4_landscape" page-height="21cm" page-width="29.7cm">
<fo:region-body region-name="body" margin="0mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:apply-templates />
</fo:root>
</xsl:template>
<!-- Form -->
<xsl:template match="post">
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="body">
<fo:block-container overflow="hidden" position="absolute" z-index="1" id="label--1-0" top="40mm" left="25.0mm" width="69.9mm" height="29.9mm" padding-top="0.5mm" padding-left="0.5mm" padding-right="0.5mm" padding-bottom="0.5mm" border-top-color="#000000" border-top-style="solid" border-top-width="0mm" border-left-color="#000000" border-left-style="solid" border-left-width="0mm" border-right-color="#000000" border-right-style="solid" border-right-width="0mm" border-bottom-color="#000000" border-bottom-style="solid" border-bottom-width="0mm" xmlns:fo="http://www.w3.org/1999/XSL/Format"><fo:block font-family="Helvetica" font-size="55pt" font-weight="bold"><![CDATA[Blz. 1]]></fo:block></fo:block-container>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="body">
<fo:block-container overflow="hidden" position="absolute" z-index="1" id="label--1-1" top="35mm" left="20.0mm" width="59.9mm" height="39.9mm" padding-top="0.5mm" padding-left="0.5mm" padding-right="0.5mm" padding-bottom="0.5mm" border-top-color="#000000" border-top-style="solid" border-top-width="0mm" border-left-color="#000000" border-left-style="solid" border-left-width="0mm" border-right-color="#000000" border-right-style="solid" border-right-width="0mm" border-bottom-color="#000000" border-bottom-style="solid" border-bottom-width="0mm" xmlns:fo="http://www.w3.org/1999/XSL/Format"><fo:block font-family="Helvetica" font-size="55pt" font-weight="bold"><![CDATA[Blz 2.]]></fo:block></fo:block-container>
</fo:flow>
</fo:page-sequence>
</xsl:template>
</xsl:stylesheet>
我需要做的是在用于转换之前更改XSL-FO
文档。我将获得一个参数,其中将指出必须包含在PDF
中的页面,并且基于此页面列出了必须排除XSL-FO
文档的相关部分。
我已经通过更改此行
实现了这一点Source xsltSrc = convertString2Source(xmlPath+".xsl");
而是使用我定义convertString2FilteredDomSource
的新函数,该函数读取文档,编辑它然后返回DOMSource
。因此,基本上,我没有使用StreamSource
而是使用DOMSource
。
以下是我convertString2FilteredDomSource
的实现:
protected static Source convertString2FilteredDomSource(String filename, String pageFilter) throws IOException, ParserConfigurationException, SAXException, XPathExpressionException
{
Document document = fileToDocument(filename);
if (!pageFilter.trim().equals("*")) {
Integer[] pages = extractPageArray(pageFilter);
XPathFactory xpf = XPathFactory.newInstance();
XPath xPath = xpf.newXPath();
NodeList items = (NodeList) xPath.evaluate("/stylesheet/template/page-sequence", document, XPathConstants.NODESET);
for (int i = items.getLength()-1; i >= 0; i--) {
if (!Arrays.asList(pages).contains(i+1)) {
Node item = (Node) items.item(i);
item.getParentNode().removeChild(item);
}
}
document.normalize();
}
return new DOMSource(document);
}
protected static Integer[] extractPageArray(String pages)
{
String[] sPageNumbers = pages.split(",");
Integer[] iPageNumbers = new Integer[sPageNumbers.length];
for (int i = 0; i < iPageNumbers.length; i++) {
iPageNumbers[i] = Integer.parseInt(sPageNumbers[i]);
}
return iPageNumbers;
}
protected static Document fileToDocument(String filename) throws IOException,ParserConfigurationException, SAXException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
return dbf.newDocumentBuilder().parse(new File(filename));
}
测试此代码时发生的情况是创建了一个空的PDF
。因此,不会抛出任何异常,但似乎返回的XSL-FO
文档不匹配任何内容,因此转换会生成一个空的PDF
文档。有谁知道为什么会出错?我怎么能让它正常工作?