1

我有一个来自我想使用 xslt 呈现的数据库的 XML 数据转储。对于我想要的布局,数据的结构不是“直截了当”的(我也将 XML 数据用于另一个报告)。

我想要的是对来自 A 级的数据进行一些计算,我需要对 C 级儿童进行分组。

我知道我可能可以再次将数据选择到一个 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元素中的值对元素进行分组。因此,您将像这样定义一个键:

<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 回答