3

特定の XML コンテンツを表形式 (PDF レポートの場合は XSL-FO) で表示する必要があり、表示するすべての列がソース XML に存在するわけではありません。そこで、特定の要素の値に基づいて追加の列を埋め込むことでソース XML を変換し、結果の XML を処理してコンテンツを表示する方法があるかどうか疑問に思っていました。

例として、ソース データの場合:

<プロジェクトチーム>
  <メンバー>
    <name>ジョン・ドウ</name>
    <role>dev</role>
 <hrs>100</hrs>
  </メンバー>
  <メンバー>
    <name>ポール・コーダー</name>
    <role>dev</role>
 <hrs>40</hrs>
  </メンバー>
  <メンバー>
    <name>ヘンリー・テスター</name>
    <role>qa</role>
 <hrs>80</hrs>
  </メンバー>
  <メンバー>
    <name>ピーター・テスター</name>
    <role>qa</role>
 <hrs>40</hrs>
  </メンバー>
</プロジェクトチーム>

データを次のように表示したい:

名前 役割 Dev QA
---------------------------
ジョン・ドウ dev 100  
ポール・コーダー dev 40
ヘンリー・テスター qa 80
ピーター・テスター qa 40
---------------------------
ロール合計: 140 120
---------------------------

次のようなものを使用できるかどうかを知りたいです。

    <xsl:要素名="{役割}">
      <xsl:value-of select="member/hrs"/>
    </xsl:要素>

要素 <dev>100</dev> などを実行時に最初のパスで埋め込み、結果の XML を使用して新しい列 'dev' と 'qa' のデータを表示し、合計を計算できるようにします。各役割タイプははるかに単純になり (たとえば、dev 列の「sum(preceding-sibling::member/dev)」)、「dev」および「qa」列の各セルのデータは単純に値になる可能性があります。これらのタグのそれぞれ。

次のスタイルシートを使用して望ましい結果を得ました (簡潔にするためにページの書式設定の詳細は省略されています) が、これが適切な解決策であるとは確信していません。

    ...
              <fo:テーブル本体>
      <!-- テーブルの行を埋めます -->
                <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:テーブルセル>

      <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:テーブルセル>
      <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:テーブルセル>
      </fo:テーブル行>
              </fo:テーブル本体>
    ...
    </fo:ルート>
  </xsl:テンプレート>

  <xsl:template match="member">
  <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:ブロック>
      <xsl:if test="role = 'dev'"><xsl:value-of select="hrs"/></xsl:if>
  </fo:ブロック>
      </fo:テーブルセル>
      <fo:table-cell text-align="right">
        <fo:ブロック>
      <xsl:if test="role = 'qa'"><xsl:value-of select="hrs"/></xsl:if>
  </fo:ブロック>
      </fo:テーブルセル>
    </fo:テーブル行>
  </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 + $ノード/時間"/>
      </xsl:いつ>
      <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:いつ>
     <xsl:それ以外の場合>
      <fo:block><xsl:value-of select="$newRT"/></fo:block>
     </xsl:そうでなければ>
   </xsl:選択>
  </xsl:テンプレート>
4

2 に答える 2

3

開発と 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>

私は XSL-FO ではなく HTML として出力しましたが、これで一般的なアイデアが得られるかもしれません。

于 2009-09-24T08:16:08.130 に答える
1

はい、できます。

あなたの質問に答えるために。本当のところ、私は巨大なスタイルシートを読んでいません。

于 2009-09-22T19:21:54.320 に答える