动态添加元素

我需要以表格形式显示某些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

上一篇: Adding Elements dynamically

下一篇: How to insert &nbsp; in XSLT