2012-09-04 84 views
3

說我有下面的XMLXSLT 1.0從多個節點添加值一起

<A>100</A> 
    <B>200</B> 
    <C>300</C> 

和下面的XSLT

<TEST> 
    <xsl:value-of select="A + B + C"/> 
    </TEST> 

它產生以下輸出

<TEST>600</TEST> 

然而,當其中一個節點爲空白

<A></A> 
    <B>200</B> 
    <C>300</C> 

我收到以下內容。

<TEST>NaN</TEST> 

我只想添加有效數字的節點。如果xsl允許我通過添加已經存在的變量來動態地替換變量值,我可以這樣做,但即使這樣也會很麻煩。我認爲有一個簡單的方法,我錯過了?

我只想要XSLT 1.0的答案。

謝謝!

+0

[在包含空值的節點集在XSLT中使用fn:sum]的可能重複(http://stackoverflow.com/questions/2279314/using-fnsum-in-xslt-with-node-set-containing -null-values) – Filburt

+0

不是重複的,因爲另一個是一個節點名稱的總和,這是將不同的節點相加在一起。再加上這就是xslt 2.0。我問1.0。 – james31rock

+0

當然不是一個完全相同的副本,但包含關於如何針對空節點進行測試的提示(不是特定於xslt 2.0)。 – Filburt

回答

6
<TEST> 
    <xsl:value-of select="sum((A | B | C)[number(.) = .])"/> 
    </TEST> 

也就是說,對元素A,B,C的子集進行求和,其中的元素可以用作數字。

請注意,number('')產生NaN(NaN = NaN)是錯誤的,所以這將不包括沒有文本內容的元素。

我們的測試針對數字作爲https://stackoverflow.com/a/3854389/423105

+0

請注意,此測試不適用於XPath 2.0,其中「無法比較xs:double到xs:string」。 – LarsH

+3

如果沒有模式,或者架構表示A,B和C是數字,它將在XPath 2.0中工作。你*可以*比較xs:double到xs:untypedAtomic。 –

+1

@MichaelKay:嗯。上述錯誤是我在沒有模式關聯的XML文檔上使用XPath 2.0時收到的。這是在Oxygen XML Editor的XPath 2.0評估器中。我想知道是否有一些我不知道的隱藏或默認模式? – LarsH

2
<xsl:value-of select="sum(/root/*[self::A or self::B or self::C][.!=''])"/> 

只要值不是空白,就會在「根」元素下添加A,B和C的值。

+0

還有其他一些我不想總結的內容。我特別想要元素A,B和C. – james31rock

+0

更新它來檢查元素名稱,嘗試新的元素名稱。 – Parker

+0

謝謝@皮克。你的答案會起作用,但LarsH的我一起去了。仍然+1 – james31rock

4

LarsH的回答的變化很小討論:

sum((A|B|C)[number(.) = number(.)]) 

謂詞表達不會引起任何類型的錯誤XPath 2.0中,因爲這兩個=的參數是相同類型的 - xs:double。

2

還有:

對於XSLT 1.0:

sum((A|B|C)[string(number())!='NaN']) 

對於XSLT 2.0:

sum((A,B,C)[string(number())!='NaN']) 

對於興趣,這裏是另外一個。它同時適用於XSLT 1.0和2.0

sum((A|B|C)[number()>-99999999]) 

在上述中,代替-99999999具有比下限可能值之一以下。這是有效的,因爲NaN> any-thing總是返回false。這可能是最有效的解決方案,但它可能被認爲有點難看。

例如,如果你知道一個事實,即沒有A,B或C的將是負值,你可以把:

sum((A|B|C)[number()>0]) 

...看起來乾淨了一點,仍然是安靜可讀。