2010-12-08 101 views
3

是否有可能執行有條件的XSL總計?XSL條件總計

我有以下XML示例:

<?xml version="1.0" encoding="utf-8"?> 
<export> 
<stats set="1"> 
    <columns> 
    <column id="0"> 
     <sum>100</sum> 
    </column> 
    <column id="1"> 
     <sum>102</sum> 
    </column> 
    <column id="2"> 
     <sum>12</sum> 
    </column> 
    </columns> 
</stats> 
    <stats set="2"> 
    <columns> 
     <column id="0"> 
     <sum>100</sum> 
     </column> 
     <column id="1"> 
     <sum>101</sum> 
     </column> 
     <column id="2"> 
     <sum>19</sum> 
     </column> 
    </columns> 
    </stats> 
</export> 

是否可以計算總在每個統計組,他們是不等於彼此的所有列的?所以它會輸出以下內容:

   Set 1  Set 2  Diff(Set 1 - Set 2) 
Total (Diff) 114   120   -6 
column 2  102   101   1 
column 3  12   19   -7 

所以在輸出列1中將被省略,因爲兩個統計集中的總和是相同的。

我可以讓我的XSL來輸出不同,但不確定該如何這些總起來,把總的行中的列。

非常感謝,

Andez

+0

編輯您的帖子以包含您的XSL – 2010-12-08 23:11:12

+0

優秀的問題+1。查看我的答案,獲得完整有效的解決方案和廣泛的解釋。 :) – 2010-12-09 02:32:30

回答

1

該轉化(64行):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:key name="kColByPosAndVal" match="column" 
    use="concat(count(preceding-sibling::*), 
       '+', 
       sum)"/> 
<xsl:key name="kIdByVal" match="column/@id" 
    use="."/> 

<xsl:template match="/*"> 
    <xsl:variable name="vsum1" select= 
    "sum(stats[@set=1]/*/column 
        [not(key('kColByPosAndVal', 
          concat(count(preceding-sibling::*), 
            '+', 
            sum) 
          )[2] 
         )])"/> 
    <xsl:variable name="vsum2" select= 
    "sum(stats[@set=2]/*/column 
        [not(key('kColByPosAndVal', 
          concat(count(preceding-sibling::*), 
            '+', 
            sum) 
          )[2] 
         )])"/> 

       Set 1   Set 2  Diff(Set 1 - Set 2) 
    Total (Diff) <xsl:text/> 
    <xsl:value-of select="$vsum1"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vsum2"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vsum1 -$vsum2"/> 
    <xsl:text>&#xA;</xsl:text> 

    <xsl:for-each select= 
    "*/*/column/@id 
     [generate-id() 
     = generate-id(key('kIdByVal',.)[1]) 
     ] 
     [not(key('kColByPosAndVal', 
       concat(count(../preceding-sibling::*), 
         '+', 
         ../sum) 
       )[2] 
      )]"> 
    <xsl:variable name="vcolSet1" select= 
    "/*/stats[@set=1]/*/column[@id=current()]/sum"/> 

    <xsl:variable name="vcolSet2" select= 
    "/*/stats[@set=2]/*/column[@id=current()]/sum"/> 
    Column <xsl:value-of select=".+1"/><xsl:text/> 
    <xsl:text>  </xsl:text> 
    <xsl:value-of select="$vcolSet1"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vcolSet2"/> 
    <xsl:text>    </xsl:text> 
    <xsl:value-of select="$vcolSet1 -$vcolSet2"/> 
    <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔應用:

<export> 
<stats set="1"> 
    <columns> 
    <column id="0"> 
     <sum>100</sum> 
    </column> 
    <column id="1"> 
     <sum>102</sum> 
    </column> 
    <column id="2"> 
     <sum>12</sum> 
    </column> 
    </columns> 
</stats> 
    <stats set="2"> 
    <columns> 
     <column id="0"> 
     <sum>100</sum> 
     </column> 
     <column id="1"> 
     <sum>101</sum> 
     </column> 
     <column id="2"> 
     <sum>19</sum> 
     </column> 
    </columns> 
    </stats> 
</export> 

產生想要的,正確的結果

    Set 1   Set 2  Diff(Set 1 - Set 2) 
    Total (Diff) 114    120    -6 

    Column 2  102    101    1 

    Column 3  12    19    -7 

說明

  1. 命名鍵用來選擇具有給定的位置(所有column兄弟姐妹之間)中的所有列併爲其sum子元素給定值。

  2. 命名kIdByVal的關鍵是Muenchian分組的用於查找的id屬性所有不同的值。

  3. 兩個總計的計算求和只有那些列,其鍵僅選擇一個column元件(如果它選擇兩個column元素,它們都在相同的位置,並且具有相同的sum)。

  4. 其餘的應該很容易理解