2009-11-12 32 views
1

我試圖在xml中使用xslt 2.0來總結數量字段,它將輸出我的設備中有一個設備的數量與多個條目,而不會被設備組求和。任何關於如何解決這個問題的想法?使用XSLT 2.0和分組總結數量

這是我使用XSLT:

<xsl:for-each-group select="//node()" group-by="*[local-name()='lin_id']/text()"> 
    <Results> 
     <xsl:element name="LIN_ID"><xsl:value-of select="*[local-name()='lin_id']"/></xsl:element> 
     <xsl:element name="Count"><xsl:value-of select="sum(current-group()/*[local-name()='qty'])"/></xsl:element> 
    </Results> 
</xsl:for-each-group> 

這裏的源XML文件:

<Equipment> 
    <lin_id>C18312</lin_id> 
    <qty>5</qty> 
    </Equipment> 
    <Equipment> 
    <lin_id>C18345</lin_id> 
    <qty>22</qty> 
    </Equipment> 
    <Equipment> 
    <lin_id>C18378</lin_id> 
    <qty>43</qty> 
    </Equipment> 
    <Equipment> 
    <lin_id>C18378</lin_id> 
    <qty>208</qty> 
    </Equipment> 

而這裏的輸出是什麼目前:

<Results> 
     <LIN_ID>C18312</LIN_Name> 
     <Count>5</Count> 
    </Results> 
    <Results> 
     <LIN_ID>C18345</LIN_Name> 
     <Count>22</Count> 
    </Results> 
     <Results> 
     <LIN_ID>C18378</LIN_Name> 
     <Count>43</Count> 
    </Results> 

所以你可以看到它正在進行分組,但是對於LIN_ID C18378,它應該將兩個條目的數量相加並輸出計數但它只是顯示其中的一個值。

回答

1

首先 - <xsl:for-each-group select="//node()" >應該做什麼?嘗試:

<xsl:for-each-group select="//Equipment" group-by="lin_id"> 
    <Results> 
    <LIN_ID> 
     <xsl:value-of select="current-grouping-key()"/> 
    </LIN_ID> 
    <Count> 
     <xsl:value-of select="sum(current-group()/qty)"/> 
    </Count> 
    </Results> 
</xsl:for-each-group> 

如果所有*[local-name()='…']業務是因爲命名空間的,我建議你讓你的命名空間聲明直。因爲這是不必要的和邊緣可怕的。 ;-)

另外:沒有必要寫<xsl:element name="LIN_ID">,你可以直接寫<LIN_ID>,如上圖所示。

出於調試的目的,你可以這樣做:

<Count qty_nodes="{count(current-group()/qty)}"> 
    <xsl:value-of select="sum(current-group()/qty)"/> 
</Count> 

,看看有多少節點current-group()/qty回報。

+0

我猜//節點()得到的是當前節點?我不知道。我繼承了這個xslt文件,並且正在學習,所以我不會在bordeline可怕的陳述中冒犯。我不得不同意其他一些xslt文件混合使用名稱空間聲明,我不知道還有什麼。你給我的工作很好。謝謝! – John81 2009-11-12 17:42:15

+0

否,// node()在整個文檔中選擇*每個單個節點*。 *一切*。你應該在XPath上做一些閱讀。 ;-)另外,「邊緣恐怖」也有笑臉。 如果我的答案有效,可以將其標記爲已接受。 Tomalak 2009-11-12 19:05:38

+0

Gotcha。我想將它標記爲答案,但我需要15個聲望並且只有10個聲望。當我有幾點時,我會回來做。 – John81 2009-11-13 22:18:56

1

該轉化

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/*"> 
     <top> 
      <xsl:for-each-group select="Equipment/lin_id" group-by="."> 
      <Results> 
       <LIN_ID> 
       <xsl:sequence select="current-grouping-key()"/> 
       </LIN_ID> 
       <Count> 
       <xsl:sequence select="sum(current-group()/../qty/xs:integer(.))"/> 
       </Count> 
      </Results> 
      </xsl:for-each-group> 
     </top> 
    </xsl:template> 
</xsl:stylesheet> 

當針對所提供的輸入施加(校正爲一個簡潔(wellformed)XML文件):

<t> 
    <Equipment> 
     <lin_id>C18312</lin_id> 
     <qty>5</qty> 
    </Equipment> 
    <Equipment> 
     <lin_id>C18345</lin_id> 
     <qty>22</qty> 
    </Equipment> 
    <Equipment> 
     <lin_id>C18378</lin_id> 
     <qty>43</qty> 
    </Equipment> 
    <Equipment> 
     <lin_id>C18378</lin_id> 
     <qty>208</qty> 
    </Equipment> 
</t> 

產生想要的結果

<top> 
    <Results> 
     <LIN_ID>C18312</LIN_ID> 
     <Count>5</Count> 
    </Results> 
    <Results> 
     <LIN_ID>C18345</LIN_ID> 
     <Count>22</Count> 
    </Results> 
    <Results> 
     <LIN_ID>C18378</LIN_ID> 
     <Count>251</Count> 
    </Results> 
</top> 
+0

爲什麼''而不是''? – Tomalak 2009-11-18 12:54:17

+0

在XSLT 2.0中,始終使用並僅使用生成文本節點是一種好習慣。只有當我們確信該值將在最終輸出中時,它們纔是等價的。即使如此,如果該值不是* complete *輸出,最好使用。如果我們使用,那麼創建的文本節點將不得不與其他文本節點合併以產生最終輸出。 總之:總是使用。 我在一些特殊情況下使用:當我輸出多個值並想使用@separator屬性時。 – 2009-11-18 14:02:32