XSLT fop-0.95:dyn的问题:评估

时间:2009-10-05 16:28:20

标签: xslt dynamic apache-fop evaluate

我一直在努力解决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>

由于

2 个答案:

答案 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文件。