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