XSLT-动态添加元素

XSLT-动态添加元素,xslt,element,Xslt,Element,我需要以表格形式显示某些XML内容(用于pdf报告的XSL-FO), 并且并非所有要显示的列都存在于源XML中。所以,我想知道 如果有一种方法可以通过嵌入基于 然后处理生成的XML以显示内容 例如,对于源数据: <projectteam> <member> <name>John Doe</name> <role>dev</role> <hrs>100</hrs> </member> <member>

我需要以表格形式显示某些XML内容(用于pdf报告的XSL-FO), 并且并非所有要显示的列都存在于源XML中。所以,我想知道 如果有一种方法可以通过嵌入基于 然后处理生成的XML以显示内容

例如,对于源数据:

<projectteam> <member> <name>John Doe</name> <role>dev</role> <hrs>100</hrs> </member> <member> <name>Paul Coder</name> <role>dev</role> <hrs>40</hrs> </member> <member> <name>Henry Tester</name> <role>qa</role> <hrs>80</hrs> </member> <member> <name>Peter Tester</name> <role>qa</role> <hrs>40</hrs> </member> </projectteam> 无名氏 发展 100 保罗编码器 发展 40 亨利测试仪 质量保证 80 彼得测试仪 质量保证 40 我希望数据显示为:

Name Role Dev QA --------------------------- John Doe dev 100 Paul Coder dev 40 Henry Tester qa 80 Peter Tester qa 40 --------------------------- Role Totals: 140 120 --------------------------- 名称角色开发人员QA --------------------------- 无名氏开发100 保罗编码器开发40 亨利测试仪qa 80 彼得测试仪qa 40 --------------------------- 职位总数:140 120 --------------------------- 我想知道我是否可以使用以下内容:

<xsl:element name="{role}"> <xsl:value-of select="member/hrs"/> </xsl:element> 这样我就可以在运行时在 首先传递,然后使用生成的XML显示新列“dev”的数据 和“qa”,这样,计算每种角色类型的总数会简单得多 (例如,dev列的“sum(前面的同级::member/dev)”以及每个列的数据) “dev”和“qa”列中的单元格可以分别是这些标记的值

通过使用以下样式表(页面格式),它获得了预期的结果 细节省略以保持简洁),但我不相信这是合适的解决方案

... <fo:table-body> <!-- fills table rows --> <xsl:apply-templates select="member"/> <!-- dislpay totals for each role --> <fo:table-row height="12pt" border-bottom="1pt solid black"> <fo:table-cell number-columns-spanned="2"> <fo:block>Role Totals:</fo:block> </fo:table-cell> <fo:table-cell text-align="right"> <xsl:call-template name="RoleTotals"> <xsl:with-param name="node" select="//member[1]"/> <xsl:with-param name="roleName" select="'dev'"/> </xsl:call-template> </fo:table-cell> <fo:table-cell text-align="right"> <xsl:call-template name="RoleTotals"> <xsl:with-param name="node" select="//member[1]"/> <xsl:with-param name="roleName" select="'qa'"/> </xsl:call-template> </fo:table-cell> </fo:table-row> </fo:table-body> ... </fo:root> </xsl:template> <xsl:template match="member"> <fo:table-row border-bottom="1pt solid black"> <fo:table-cell> <fo:block> <xsl:value-of select="name"/></fo:block></fo:table-cell> <fo:table-cell> <fo:block> <xsl:value-of select="role"/></fo:block></fo:table-cell> <fo:table-cell text-align="right"> <fo:block> <xsl:if test="role = 'dev'"><xsl:value-of select="hrs"/></xsl:if> </fo:block> </fo:table-cell> <fo:table-cell text-align="right"> <fo:block> <xsl:if test="role = 'qa'"><xsl:value-of select="hrs"/></xsl:if> </fo:block> </fo:table-cell> </fo:table-row> </xsl:template> <xsl:template name="RoleTotals"> <xsl:param name="node"/> <xsl:param name="roleName"/> <xsl:param name="RT" select="0"/> <xsl:variable name="newRT"> <xsl:choose> <xsl:when test="$node/role = $roleName"> <xsl:value-of select="$RT + $node/hrs"/> </xsl:when> <xsl:otherwise><xsl:value-of select="$RT"/></xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:choose> <xsl:when test="$node/following-sibling::member"> <xsl:call-template name="RoleTotals"> <xsl:with-param name="node" select="$node/following-sibling::member[1]"/> <xsl:with-param name="roleName" select="$roleName"/> <xsl:with-param name="RT" select="$newRT"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <fo:block><xsl:value-of select="$newRT"/></fo:block> </xsl:otherwise> </xsl:choose> </xsl:template> ... 角色总数: ... 是的,你可以


回答你的问题。老实说,我还没有读过庞大的样式表。

如果添加了更多的工作角色,而不是开发人员和质量保证人员,会发生什么?你的样式表能应付吗?也许您可以使用Muenchian分组来获取样式表中所有可能的角色,然后为每个可能的角色动态生成列

<xsl:key name="roles" match="role" use="."/>

<xsl:template match="/projectteam">
 <table border="1">
  <tr>
   <td>Name</td>
   <td>Role</td>
   <xsl:for-each select="member[generate-id(role) = generate-id(key('roles', role)[1])]">
    <td>
     <xsl:value-of select="role"/>
    </td>
   </xsl:for-each>
  </tr>
  <xsl:apply-templates select="member"/>
 </table>
</xsl:template>

<xsl:template match="member">
 <xsl:variable name="currentrole" select="role"/>
 <xsl:variable name="currenthrs" select="hrs"/>
 <tr>
  <td>
   <xsl:value-of select="name"/>
  </td>
  <td>
   <xsl:value-of select="role"/>
  </td>
  <xsl:for-each select="/projectteam/member[generate-id(role) = generate-id(key('roles', role)[1])]">
   <td>
    <xsl:choose>
     <xsl:when test="$currentrole = role">
      <xsl:value-of select="$currenthrs"/>
     </xsl:when>
    </xsl:choose>
   </td>
  </xsl:for-each>
 </tr>
</xsl:template>

名称
角色

我以HTML的形式输出,而不是XSL-FO,但这可能给了您一个大概的想法。

您能建议如何输出吗?我试过各种组合,但都没用。我遇到的真正问题有点复杂,即我有一个邮件元素,它可以有多个容器,每个容器都可以有多个包。每个bundle都是特定的LevelType,并且有一个描述TotalPieces的元素。因此,在列中显示每个buldle的总件数,在底部显示每个LevelType的总件数变得更加复杂。这就是我非常怀念添加新元素(即LevelType w/值设置为TotalPieces)的能力的地方。感谢您所说的:
(在您的示例中,当然是在
成员的上下文中)。我以为你没试过。什么对您不起作用,说什么也不起作用?好吧,我添加了一个新模板:xsl:template match=“member”>xsl:element name=“{role}”>xsl:value of select=“hrs”/>xsl:apply templates select=“member”/>/xsl:element>/xsl:template>,并尝试在现有模板中为member使用元素,但没有成功(尽管我仍然不清楚模板)我尝试在现有模板中为成员添加以下行:xsl:element name=“{role}”>xsl:value of select=“hrs”/>/xsl:element>,我得到的只是来自FOP的一条关于未知格式对象的警告。第二次尝试:(prev.post变得混乱)1.2.(从成员的现有模板中):两者都不起作用,但fop不应该识别
元素。我宁愿一步一步解决问题。首先,你需要为fop生成输入,看看它是否是你想要的。将你的想法建立在修复仅基于fop消息生成的xml上,对我来说听起来是错误的。谢谢!!我已经尝试了这个方法,现在它已经成功了Works gereat!这真是一个很好的通用解决方案!现在我知道了“generate0id()”和key元素的一些用例!我已经固定了一组类似“role”的列(尽管有11个),因此这种方法将大大减少代码量,但再次动态引入11个新元素将使最终合计它们变得更加容易。我将尝试这种方法和多通道样式表(使用node-set()),看看哪一种更有意义。谢谢