0.95:dyn问题:评估
我一直在努力处理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>
(注意:这是一个模拟的例子,但我有一个非常类似的需求,我需要在工作结束时生成类似于角色类型的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)运行它以生成.fo,然后使用fop将该.fo转换为pdf,我的xsl样式表就会按预期工作。 但是,当我直接使用fop(即单步:fop -xml blah.xml -xsl blah.xsl -pdf out.pdf)时,我得到了奇怪的结果 - 只有第一列的数据(即第一个子元素' RoleTypes',在这个例子中是'dev'),其余的colums是空白的。 我也试着先用fop生成.fo(-foout选项),然后使用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>
谢谢
这并不回答使用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>
你会得到你想要的输出。
正如在http://markmail.org/message/np4t6fe4nsmr4vag中指出的那样,这不是直接的FOP问题,而是一个使用在Java安装中处于活动状态的默认XSLT处理器的问题。 XSLT处理器可能需要按照此处所述进行明确替换:http://xml.apache.org/xalan-j/faq.html#faq-N100EF
当然,您也可以继续使用xsltproc生成XSL-FO,然后将FOP文件提供给FOP。
链接地址: http://www.djcxy.com/p/34327.html