3

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

例如,对于源数据:

<项目团队>
  <成员>
    <name>约翰·多伊</name>
    <角色>开发</角色>
 <hrs>100</hrs>
  </会员>
  <成员>
    <name>保罗编码员</name>
    <角色>开发</角色>
 <hrs>40</hrs>
  </会员>
  <成员>
    <name>亨利泰斯特</name>
    <角色>qa</角色>
 <hrs>80</hrs>
  </会员>
  <成员>
    <name>彼得测试员</name>
    <角色>qa</角色>
 <hrs>40</hrs>
  </会员>
</项目团队>

我希望数据显示为:

姓名 角色 开发 QA
--------------------------
John Doe 开发 100  
保罗编码器开发 40
亨利测试仪 qa 80
彼得测试员 QA 40
--------------------------
角色总数:140 120
--------------------------

我想知道我是否可以使用类似的东西:

    <xsl:element name="{role}">
      <xsl:value-of select="member/hrs"/>
    </xsl:元素>

这样我就可以在第一次通过时在运行时嵌入元素 <dev>100</dev> 等,然后使用生成的 XML 显示新列“dev”和“qa”的数据,这样,计算总计每个角色类型都将简单得多(例如,dev 列的“sum(preceding-sibling::member/dev)”),'dev' 和 'qa' 列中每个单元格的数据可能只是值-这些标签分别。

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

    ...
              <fo:table-body>
      <!-- 填充表格行 -->
                <xsl:apply-templates select="member"/>

      <!-- 显示每个角色的支付总数 -->
      <fo:table-row height="12pt" border-bottom="1pt 纯黑色">
      <fo:table-cell number-columns-spanned="2">
        <fo:block>角色总数:</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:调用模板>
      </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:调用模板>
      </fo:table-cell>
      </fo:table-row>
              </fo:table-body>
    ...
    </fo:root>
  </xsl:模板>

  <xsl:template match="成员">
  <fo:table-row border-bottom="1pt 纯黑色">
      <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:模板>

  <xsl:template name="RoleTotals">
    <xsl:param name="节点"/>
    <xsl:param name="roleName"/>
    <xsl:param name="RT" select="0"/>
    <xsl:变量名="newRT">
    <xsl:选择>
      <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:选择>
    </xsl:变量>
   <xsl:选择>
     <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:调用模板>
     </xsl:when>
     <xsl:否则>
      <fo:block><xsl:value-of select="$newRT"/></fo:block>
     </xsl:否则>
   </xsl:选择>
  </xsl:模板>
4

2 回答 2

3

如果添加了除 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,但也许这给了你大致的想法。

于 2009-09-24T08:16:08.130 回答
1

是的你可以。

回答你的问题。我还没有读过巨大的样式表,这是真的。

于 2009-09-22T19:21:54.320 回答