2011-08-26 81 views
0

嗨,我想在XSLT中進行一些聚合。例如,我有以下xml文件。如何在xslt中進行聚合1.0

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> 
<reporting:root xmlns:reporting="testing"> 
    <reporting:default0 reporting:type="Portfolio"> 
    <reporting:window reporting:Id="1" reporting:level="0" reporting:name="TEST" reporting:parentId="-1"> 
     <reporting:folio reporting:Id="2" reporting:criteria="0" reporting:level="1" reporting:name="topfolder1" reporting:parentId="1"> 
     <reporting:folio reporting:Id="37" reporting:criteria="0" reporting:level="2" reporting:name="folder2" reporting:parentId="2"> 
      <reporting:folio reporting:Id="38" reporting:criteria="0" reporting:level="3" reporting:name="folder3" reporting:parentId="37"> 
      <reporting:folio reporting:Id="196" reporting:criteria="0" reporting:level="4" reporting:name="folder4" reporting:parentId="38"> 
       <reporting:line reporting:Id="123456" reporting:level="5" reporting:name="element1" reporting:parentId="196" reporting:positionType="0"> 
       <reporting:reference>element1</reporting:reference> 
       <reporting:number>625</reporting:number> 
       </reporting:line> 
       <reporting:line reporting:Id="223456" reporting:level="5" reporting:name="element2" reporting:parentId="196" reporting:positionType="7"> 
       <reporting:reference>element2</reporting:reference> 
       <reporting:number>475</reporting:number> 
       </reporting:line> 
       <reporting:folio reporting:Id="209" reporting:criteria="0" reporting:level="5" reporting:name="delta" reporting:parentId="196"> 
       <reporting:line reporting:Id="223456" reporting:level="6" reporting:name="element2" reporting:parentId="209" reporting:positionType="0"> 
        <reporting:reference>element2</reporting:reference> 
        <reporting:number>190</reporting:number> 
       </reporting:line> 
       </reporting:folio> 
      </reporting:folio> 
      </reporting:folio> 
     </reporting:folio> 
     </reporting:folio> 
     <reporting:folio reporting:Id="4" reporting:criteria="0" reporting:level="1" reporting:name="topfolder2" reporting:parentId="1"> 
     <reporting:folio reporting:Id="39" reporting:criteria="0" reporting:level="2" reporting:name="folder24" reporting:parentId="4"> 
      <reporting:folio reporting:Id="40" reporting:criteria="0" reporting:level="3" reporting:name="folder34" reporting:parentId="39"> 
      <reporting:folio reporting:Id="296" reporting:criteria="0" reporting:level="4" reporting:name="folder44" reporting:parentId="40"> 
       <reporting:line reporting:Id="123456" reporting:level="5" reporting:name="element3" reporting:parentId="296" reporting:positionType="0"> 
       <reporting:reference>element3</reporting:reference> 
       <reporting:number>65525</reporting:number> 
       </reporting:line> 
       <reporting:folio reporting:Id="309" reporting:criteria="0" reporting:level="5" reporting:name="delta" reporting:parentId="296"> 
       <reporting:line reporting:Id="2234567" reporting:level="6" reporting:name="element4" reporting:parentId="309" reporting:positionType="0"> 
        <reporting:reference>element4</reporting:reference> 
        <reporting:number>490</reporting:number> 
       </reporting:line> 
       </reporting:folio> 
      </reporting:folio> 
      </reporting:folio> 
     </reporting:folio> 
     </reporting:folio> 
    </reporting:window> 
    </reporting:default0> 
</reporting:root> 

然後我想在'2級'做一些聚合。即「報告:行」內的任何內容都應返回,並且它是1級和2級父級報告:「folio」也應返回。同樣對於level2文件夾的anysubfolder下的相同元素應該聚合爲一個。並且還計算總和(數字)。

也沒有。在有報告:行標記之前,子作品集可以是200。

所以這個XML我想要得到的結果是:

topfolder,folder2,element1,625 
topfolder,folder2,element2,665 
topfolder2,folder24,element3,65525 
topfolder2,folder24,element4,490 

希望我正確解釋它。非常感謝您的幫助。

+0

有y你自己試過什麼?這似乎是相當基本的xslt;趕上一個教程,你已經超過了你的解決方案的一半。 – Wivani

+0

你能指出一個好的教程嗎?我在線上進行了研究,但都使用了xslt 2.0函數。我正在使用xslt 1.0 – ken

+0

http://www.w3schools.com/xsl/ – Wivani

回答

2

在這種情況下,您需要首先進行分組,然後進行聚合。您需要按照作品集級別1,作品集級別2和元素名稱對元素進行分組。要做到這一點,你通常使用Muenchian分組的方法。

首先,定義一個的xsl:鍵其可用於將所有匹配元素一起

<xsl:key name="lines" match="reporting:line" use=" 
concat(
concat(
    concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','), 
    concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',') 
), 
@reporting:name 
)" /> 

接下來,就需要選擇各組中的第一匹配部件。

<xsl:apply-templates select="//reporting:line 
    [generate-id() = 
    generate-id(key('lines', ...concatenated key... )[1])]" /> 

然後,它是當應用到總結匹配查找鍵

<xsl:value-of select="sum(key('lines', $keyName)/reporting:number)" /> 

把這個完全給

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:reporting="testing"> 
    <xsl:output method="text" indent="yes"/> 

    <xsl:key name="lines" match="reporting:line" use="concat(concat(concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','), concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',')), @reporting:name)" /> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="//reporting:line[generate-id() = generate-id(key('lines', concat(concat(concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','), concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',')), @reporting:name))[1])]" /> 
    </xsl:template> 

    <xsl:template match="reporting:line"> 
     <xsl:variable name="keyName" select="concat(concat(concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','), concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',')), @reporting:name)" /> 
     <xsl:value-of select="$keyName" /> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="sum(key('lines', $keyName)/reporting:number)" /> 
     <xsl:text>&#13;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

所有元素的「簡單」的情況下,你示例XML,輸出如下:

topfolder1,folder2,element1,625 
topfolder1,folder2,element2,665 
topfolder2,folder24,element3,65525 
topfolder2,folder24,element4,490 
+0

非常感謝您的詳細解釋。現在都是有道理的,我也多了一點點去教育自己。非常感謝。我的問題是我從來沒有系統地學習過XSLT,所以有時候不知道我應該看看什麼函數。你能否推薦任何可以幫助我完成初學者的書?謝謝。 – ken