DOMSource中返回的XSLT文档生成空PDF

时间:2015-07-31 14:17:49

标签: java xslt xsl-fo

我正在尝试使用Java文档更改XMLPDF呈现为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文档。有谁知道为什么会出错?我怎么能让它正常工作?

0 个答案:

没有答案