我一直在努力解决fop 0.95的奇怪行为(不知道我是否正在做 有些不对劲,或者是否有解决方法)。
我有一个自动生成的XML,如下所示:
<projectteam> <projectname>Report Generation</projectname> <RoleTypes> <dev/> <qa/> <doc/> </RoleTypes> <member> <name>John</name> <dev>200</dev> </member> <member> <name>Max</name> <dev>60</dev> </member> <member> <name>Henry</name> <qa>80</qa> </member> <member> <name>Peter</name> <qa>40</qa> </member> </projectteam>
(注意:这是一个模拟的例子,但我需要的地方非常相似 使用类似于roleTypes的sevaral colums在作业结束时生成报告
我的目标是以pdf格式显示上述数据:
Name | dev | qa | doc | -------------------------- John | 100 | | | Max | 60 | | | Henry | | 80 | | Peter | | 40 | |
我使用xsl:for-each循环使用RoleTypes / *元素来定义表列,以及 然后动态构造XPath表达式(使用dyn:evaluate of exslt)来获取 与角色(dev,qa和doc)对应的单元格的数据。
如果我通过预处理器(xsltproc)运行它,我的xsl样式表按预期工作 生成.fo,然后使用fop将此.fo转换为pdf。 但是,当我直接使用fop时(即单步:fop -xml blah.xml -xsl blah.xsl) -pdf out.pdf),我得到了奇怪的结果 - 只有第一列的数据(即第一列) 'RoleTypes'的子元素,在此示例中为'dev'),其余的colums为空。 我也尝试用fop本身(-foout选项)生成.fo,然后使用 fop生成pdf,但得到相同的结果,即数据只显示在 与RoleTypes元素的第一个子元素对应的列。 这是fop的一个错误(因为它似乎认出了dyn:评估,但是 没做完整的工作)?
我真的想使用单步fop,这样我就不需要了 在客户端盒上部署其他工具(如xsltproc等)。
以下是我一直使用的样式表的关键部分:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:dyn="http://exslt.org/dynamic"> <xsl:template match="projectteam"> ... <fo:table table-layout="fixed" width="100%"> <fo:table-column column-width="3cm"/> <xsl:for-each select="RoleTypes/*"> <fo:table-column column-width="1cm"/> </xsl:for-each> <fo:table-body> <xsl:for-each select="member"> <xsl:variable name="Member" select="."/> <fo:table-row> <fo:table-cell> <fo:block> <xsl:value-of select="name"/></fo:block> </fo:table-cell> <xsl:for-each select="../RoleTypes/*"> <xsl:variable name="roleName" select="concat('$Member/', name(.))"/> <fo:table-cell><fo:block> <!-- This is where the problem is with fop; although the same statement works fine with xsltproc?? --> <xsl:value-of select="dyn:evaluate($roleName)"/> </fo:block></fo:table-cell> </xsl:for-each> </fo:table-row> </xsl:for-each> </fo:table-body> </fo:table> </xsl:template> </xsl:stylesheet>
由于
答案 0 :(得分:2)
这并没有回答使用dyn的一般问题:在FOP中进行评估,但对于这个特定的模式和问题,不需要动态评估。您可以使用name()函数来匹配节点名称。如果用以下代码替换示例的内循环:
<xsl:for-each select="../RoleTypes/*">
<xsl:variable name="roleName" select="name(.)"/>
<fo:table-cell><fo:block>
<xsl:value-of select="$Member/*[name()=$roleName]"/>
</fo:block></fo:table-cell>
</xsl:for-each>
您将获得所需的输出。
答案 1 :(得分:1)
正如在http://markmail.org/message/np4t6fe4nsmr4vag中所指出的,这不是直接的FOP问题,而是具有在Java安装中处于活动状态的默认XSLT处理器的问题。 XSLT处理器可能需要明确替换,如下所述: http://xml.apache.org/xalan-j/faq.html#faq-N100EF
当然,您也可以继续使用xsltproc生成XSL-FO,然后将FOP提供给FO文件。