1

ToDoList( http://www.abstractspoon.com/tdl_resources.html )のXMLファイルからクロス集計テーブルを作成しようとしています。XMLファイルの例を次に示します。

<?xml version="1.0" encoding="utf-16" ?>
<TODOLIST PROJECTNAME="Projects">
    <TASK TITLE="proj1" ID="1" NUMPERSON="1" PERSON="Chris" NUMTAGS="1" TAG="Caro" CALCTIMEESTIMATE="36"/>
    <TASK TITLE="proj2" ID="2" NUMPERSON="1" PERSON="Chris" NUMTAGS="1" TAG="Nat" CALCTIMEESTIMATE="8" />
    <TASK TITLE="proj4" ID="4" NUMPERSON="1" PERSON="Chris" NUMTAGS="1" TAG="Caro" CALCTIMEESTIMATE="36" />
    <TASK TITLE="proj5" ID="5" NUMPERSON="1" PERSON="Sahb" NUMTAGS="1" TAG="Nat" CALCTIMEESTIMATE="128" />
    <TASK TITLE="proj32" ID="32" NUMPERSON="2" PERSON="Seb" PERSON1="Chris" NUMTAGS="1" TAG="Nat" CALCTIMEESTIMATE="0.90" />
</TODOLIST>

各タスクは要素であり、すべての情報は属性です。このようなテーブルを、タグを一番上の行、人を最初の列として作成したいと思います。

<table>
    <tr>
        <td></td>
        <td>Caro</td>
        <td>Nat</td>
    </tr>
    <tr>
        <td>Chris</td>
        <td>72</td>
        <td>8</td>
    </tr>
    <tr>
        <td>Sahb</td>
        <td>128</td>
        <td>0</td>
    </tr>
    <tr>
        <td>Seb, Chris</td>
        <td>0</td>
        <td>9</td>
    </tr>
</table>

ご覧のとおり、同じ人が多くのプロジェクトを持つことができるので、タグに基づいて各人のCALCTIMEESTIMATEを合計したいと思います。私は最初の行を得ることができます

<xsl:key name="dtag" match="/TODOLIST/TASK/@TAG" use="." />
<xsl:for-each select="TASK/@TAG[generate-id() = generate-id(key('dtag', .)[1])]">
    <td>
      <xsl:value-of select="."/>
    </td>
</xsl:for-each>

ただし、sum関数では目的の結果が得られません。何が足りないの?2つの属性に基づいて合計を行う簡単な方法はありますか?ToDoListはXSLT1.0を使用しているため、distinct-valuesを使用できませんでした。

これが完全なXSLTです。私はさまざまなことを試しました。ここでは、Chrisのためだけに機能させようとしましたが、彼の2つのプロジェクトを合計することはできませんでした。

<xsl:template match="TODOLIST">
<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>
<html>
<head>
<title>Projects..</title>
</head>
<body>
<table>
<caption>Projects..</caption>
<thead>
<tr>
<td></td>

<xsl:for-each select="TASK/@TAG[generate-id() = generate-id(key('dtag', .)[1])]">
    <th scope="col">
      <xsl:value-of select="."/>
    </th>
</xsl:for-each>

</tr>
</thead>
<tbody>
<xsl:apply-templates select="TASK/@PERSON[generate-id() = generate-id(key('dperson', .)[1])]" />
</tbody>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="TASK/@PERSON">
    <tr>
        <th scope="row">
          <xsl:value-of select="."/>
        </th>
        <xsl:apply-templates select="/TODOLIST/TASK/@TAG[generate-id() = generate-id(key('dtag', .)[1])]" />
    </tr>
</xsl:template>

<xsl:template match="/TODOLIST/TASK/@TAG">
    <td>
        <xsl:value-of select="sum(../@CALCTIMEESTIMATE[../@PERSON = 'Chris'])" />
    </td>
</xsl:template>
4

1 に答える 1

0

合計を機能させるには、現在の人物と現在のタグの両方を知っている必要があります。

TASK / @ PERSONに一致する現在のテンプレートで、属性の現在の値を次のテンプレートに渡す必要があります

<xsl:apply-templates 
   select="/TODOLIST/TASK/@TAG[generate-id() = generate-id(key('dtag', .)[1])]">
     <xsl:with-param name="PERSON" select="." />
</xsl:apply-templates>

次に、@ TAGに一致するテンプレートで、SUMの「dperson」キーにアクセスできるため、次のように、その人と現在のタグのすべてのタスクを合計できます。

<xsl:template match="/TODOLIST/TASK/@TAG">
  <xsl:param name="PERSON" />
  <td>
    <xsl:value-of 
      select="sum(key('dperson', $PERSON)[../@TAG = current()]/../@CALCTIMEESTIMATE)"/>
  </td>
</xsl:template>
于 2012-10-16T16:46:28.610 に答える