动态添加元素
我需要以表格形式显示某些XML内容(用于pdf报告的XSL-FO),并且不是所有要显示的列都存在于源XML中。 所以,我想知道是否有办法通过嵌入基于某些元素值的额外列来转换源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>
我希望数据显示为:
Name Role Dev QA --------------------------- John Doe dev 100 Paul Coder dev 40 Henry Tester qa 80 Peter Tester qa 40 --------------------------- Role Totals: 140 120 ---------------------------
我想知道我是否可以使用像这样的东西:
<xsl:element name="{role}"> <xsl:value-of select="member/hrs"/> </xsl:element>
因此,我可以在第一遍时在运行时嵌入元素<dev> 100 </ dev>等,然后使用生成的XML显示新列“dev”和“qa”的数据,这样计算总数每个角色类型将会简单得多(例如,dev列中的“sum(preceding-sibling :: member / dev)”),并且'dev'和'qa'colums中每个单元格的数据都可以简单地成为值 - 这些标签分别。
它使用下面的样式表(页面格式详细信息被省略以保持简短)得到了期望的结果,但我不相信这是适合的解决方案。
... <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>
是的你可以。
回答你的问题。 我没有阅读过这个庞大的样式表,是真的。
如果增加了除Dev和QA之外的更多工作角色,会发生什么? 你的样式表能够应付吗? 也许你可以利用Muenchian Grouping在样式表中获得所有可能的角色,然后为每个可能的角色动态生成列?
<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,但也许这会给你一个总体思路。
链接地址: http://www.djcxy.com/p/34325.html