1

xslt を使用して提示したいデータベースからの XML データダンプがあります。データの構造は、必要なレイアウトに対して「単純」ではありません (別のレポートにも XML データを使用します)。

私が欲しいのは、レベル C の子をグループ化する必要があるレベル A からのデータに対していくつかの計算を行うことです。

おそらくデータを再度選択して、レポートの構造が「簡単」な XML ファイルにすることができることはわかっていますが、XSLT 自体でも実現できると感じているため、これは最後の手段です。ほとんどの場合、それを行うには「Muenchian」のトリックが必要ですが、私は「Muenchian Virgin」であるため、すべての試みで行き詰まります(「盗んで」変更しようとしています...)。

Muenchian が進むべき道であるかどうかを知っている人はいますか?誰かが正しい軌道に乗るのを手伝ってくれますか? 私はいくつかの読書をしました(Jeni Tennisonを含む)が、これまでに見たものは、私が知る限り私の問題をカバーしていません...

以下は、私の実際の問題を (多かれ少なかれ) 代表する単純化された XML 構造です。

何か案は?

よろしく、ヘンク

単純化された XML:

<data>
  <a>
    <a_id>A1</a_id>
    <a_desc>A one</a_desc>
    <a_val>1</a_val>
    <b>
      <c>
        <c_id>C2</c_id>
        <c_desc>C two</c_desc>
      </c>
    </b>
  </a>
  <a>
    <a_id>A2</a_id>
    <a_desc>A two</a_desc>
    <a_val>2</a_val>
    <b>
      <c>
        <c_id>C2</c_id>
        <c_desc>C two</c_desc>
      </c>
    </b>
  </a>
  <a>
    <a_id>A3</a_id>
    <a_desc>A three</a_desc>
    <a_val>3</a_val>
    <b>
      <c>
        <c_id>C1</c_id>
        <c_desc>C one</c_desc>
      </c>
    </b>
  </a>
  <a>
    <a_id>A4</a_id>
    <a_desc>A four</a_desc>
    <a_val>7</a_val>
    <b>
      <c>
        <c_id>C3</c_id>
        <c_desc>C three</c_desc>
      </c>
    </b>
  </a>
  <a>
    <a_id>A5</a_id>
    <a_desc>A five</a_desc>
    <a_val>11</a_val>
    <b>
      <c>
        <c_id>C1</c_id>
        <c_desc>C one</c_desc>
      </c>
    </b>
  </a>
</data>

必要な出力は次のようになります。

C_desc  Count() Sum(a_val)  Avg(a_val) 
------  ------- ----------  ----------
C one       3       15          5
C two       1       2           2
C three     1       7           7
4

1 に答える 1

1

あなたが言及したように、Muenchian グループ化は (XSLT1.0 で) 進むべき道です。c要素の値を使用して、a要素をグループ化したいと言います。したがって、次のようにキーを定義します。

<xsl:key name="a" match="a" use="b/c/c_desc" />

次に、特定のキーのグループ内の最初の要素である要素を選択することによって「個別の」要素を取得する必要があります。かなり怖い表情でやってます

<xsl:apply-templates 
     select="//a[generate-id() = generate-id(key('a', b/c/c_desc)[1])]" />

ここでkey('a', b/c/c_desc)[1]は、キーのグループの最初の要素を見つけてgenerate-id、要素を比較するために使用します。

次に、個別の a要素に一致するテンプレートがあり、この中でグループに対して計算を行うことができます。たとえば、合計を取得するには:

<xsl:value-of select="sum(key('a', b/c/c_desc)/a_val)" />

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="exsl">
   <xsl:output method="html" indent="yes"/>
   <xsl:key name="a" match="a" use="b/c/c_desc" />
   <xsl:template match="/">
      <table>
         <tr>
            <td>C_desc</td>
            <td>Count</td>
            <td>Sum</td>
            <td>Avg</td>
         </tr>
      <xsl:apply-templates select="//a[generate-id() = generate-id(key('a', b/c/c_desc)[1])]" />
      </table>
   </xsl:template>

   <xsl:template match="a">
      <xsl:variable name="c_desc" select="b/c/c_desc" />
      <tr>
         <td><xsl:value-of select="count(key('a', $c_desc))" /></td>
         <td><xsl:value-of select="sum(key('a', $c_desc)/a_val)" /></td>
         <td><xsl:value-of select="sum(key('a', $c_desc)/a_val) div count(key('a', $c_desc))" /></td>
      </tr>
   </xsl:template>
</xsl:stylesheet>

サンプル XML に適用すると、次のように出力されます。

<table>
   <tr>
      <td>C_desc</td>
      <td>Count</td>
      <td>Sum</td>
      <td>Avg</td>
   </tr>
   <tr>
      <td>3</td>
      <td>15</td>
      <td>5</td>
   </tr>
   <tr>
      <td>1</td>
      <td>2</td>
      <td>2</td>
   </tr>
   <tr>
      <td>1</td>
      <td>7</td>
      <td>7</td>
   </tr>
</table>
于 2012-09-04T14:52:58.930 に答える