【发布时间】:2016-10-07 02:11:00
【问题描述】:
我正在尝试从我拥有的 XML 文件创建 PDF,到目前为止,它使用 XSL-FO/Apache FOP 运行良好。
XML 文件基本上包含条码信息:条码本身和条码类型(我会在某个时候添加条码图像)。
现在我希望看到的输出是这样的:
-----------------------
| barcode1 | barcode2 |
| codetype1 | codetype2 |
-----------------------
| barcode3 | barcode4 |
| codetype3 | codetype4 |
-----------------------
等等。
我已经定义了以下 xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">
<xsl:template match="barcode-list">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simpleA4">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="10pt">
<fo:table table-layout="fixed" width="100%" border-collapse="separate">
<fo:table-column column-width="45%"/>
<fo:table-column column-width="45%"/>
<fo:table-body>
<xsl:apply-templates select="item"/>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="item">
<fo:table-row>
<fo:table-cell>
<fo:block wrap-option="wrap">
<xsl:value-of select="name"/>
</fo:block>
<fo:block wrap-option="wrap">
<xsl:value-of select="format"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
</xsl:stylesheet>
所以有两列,我想我可以将它指向“项目”模板来填充单元格。
现在我意识到“项目”模板包含一个<table-row> 标记,这会导致每个项目出现在自己的表格行中。所以我得到的是:
-----------------------
| barcode1 | |
| codetype1 | |
-----------------------
| barcode2 | |
| codetype2 | |
-----------------------
| barcode3 | |
| codetype3 | |
-----------------------
| barcode4 | |
| codetype4 | |
-----------------------
我的问题是如何更改 xsl 以获得所需的输出,而不是将每个项目都放在自己的表格行中?
【问题讨论】:
-
XSLT 1.1 是一个没有任何进展的草案,被 XSLT 2.0 取代,现在/很快被 XSLT 3.0 取代。您使用的是哪种 XSLT 处理器?此外,
exclude-result-prefixes="fo"实际上什么也不做,因为输出中的每个元素都在fo命名空间中,这意味着 XSLT 处理器必须在结果中包含命名空间。最后,fo:root上的xmlns:fo="http://www.w3.org/1999/XSL/Format"在xsl:stylesheet上的xmlns:fo="http://www.w3.org/1999/XSL/Format"范围内,因此不是绝对必要的,也不影响输出。 -
@TonyGraham 如果我从文件中删除这两个元素中的任何一个,Apache FOP 会引发异常,抱怨未绑定元素和未知标签。
-
@TonyGraham 我必须对文档进行哪些更改才能使其符合 XSLT 2.0?
-
异常似乎很奇怪。删除
@exclude-result-prefixes并从fo:root中删除xmlns:fo应该可以,但是由于更改会产生异常,因此不更改会更安全。根据您显示的内容,您可以将@version值更改为2.0。 XSLT 2.0 规范的附录 J 中列出了一些极端情况,但大多数 XSLT 1.0 样式表在版本号更改后在 XSLT 2.0 处理器中都能正常工作。当然,您应该测试在更改版本号后输出不会发生变化。 -
@TonyGraham 感谢您的帮助。更改版本号工作得很好。顺便说一句:我得到的例外是:“元素“fo:table-cell”的前缀“fo”未绑定”
标签: java xml pdf xsl-fo apache-fop