2010-02-05 96 views
7

我有一個問題,試圖找出xslt上的var範圍。我實際上想要做的是忽略具有重複「旅遊編碼」的「旅行」標籤。XSLT中的變量範圍

示例XML:

<trip> 
<tourcode>X1</tourcode> 
<result>Budapest</result> 
</trip> 
<trip> 
<tourcode>X1</tourcode> 
<result>Budapest</result> 
</trip> 
<trip> 
<tourcode>X1</tourcode> 
<result>Budapest</result> 
</trip> 
<trip> 
<tourcode>Y1</tourcode> 
<result>london</result> 
</trip> 
<trip> 
<tourcode>Y1</tourcode> 
<result>london</result> 
</trip> 
<trip> 
<tourcode>Z1</tourcode> 
<result>Rome</result> 
</trip> 

XSLT處理器:

<xsl:for-each select="trip">  
    <xsl:if test="not(tourcode = $temp)"> 
     <xsl:variable name="temp" select="tour"/> 
     // Do Something (Print result!) 
    </xsl:if> 
</xsl:for-each> 

所需的輸出: 布達佩斯倫敦羅馬

+1

標題問題的本來..類似, – 2010-02-08 08:55:07

回答

8

所需的輸出:布達佩斯倫敦羅馬

你是什麼後分組按城市名稱輸出。在XSLT中有兩種常用的方法。

其中之一是這樣的:

<xsl:template match="/allTrips"> 
    <xsl:apply-templates select="trip" /> 
</xsl:template> 

<xsl:template match="trip"> 
    <!-- test if there is any preceding <trip> with the same <result> --> 
    <xsl:if test="not(preceding-sibling::trip[result = current()/result])"> 
    <!-- if there is not, output the current <result> --> 
    <xsl:copy-of select="result" /> 
    </xsl:if> 
</xsl:template> 

而另外一個被稱爲Muenchian分組的和@Rubens法里亞斯只是張貼解答,說明如何做到這一點。

+0

感謝隊友,儘管出了4個副本,但它仍然顯示2,但它讓我更接近我的想法。 – Zoheir 2010-02-07 23:04:35

+0

@Mazzi:它呢?當我用你的樣品測試它時沒有。如果您發佈與您一起工作的實際XML和XSL,我相信我可以指出哪些問題。 – Tomalak 2010-02-07 23:36:09

+0

@Tomalak:xsl和xml有點笨重,我儘量簡化它們。我不知道如果stackoverflow有發送消息功能?!所以我可以直接發給你。 – Zoheir 2010-02-08 00:39:50

24

不能更改XSLT中的變量。

因爲XSLT是一種功能性語言,所以您需要更多地考慮它作爲functional programming而不是程序性的。想想像這樣的僞代碼的變量作用域:

variable temp = 5 
call function other() 
print temp 

define function other() 
    variable temp = 10 
    print temp 

你期望輸出是什麼?它應該是10 5而不是10 10,因爲函數other中的temp與該函數外部的temp不是同一個變量。

在XSLT中是一樣的。變量一旦創建,就不能被重新定義,因爲它們是一次寫入的,可以通過設計讀取許多變量。

如果你想有條件地定義一個變量的值,你需要有條件地定義變量,就像這樣:

<xsl:variable name="temp"> 
    <xsl:choose> 
    <xsl:when test="not(tourcode = 'a')"> 
     <xsl:text>b</xsl:text> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:text>a</xsl:text> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:variable> 
<xsl:if test="$temp = 'b'"> 
    <!-- Do something --> 
</xsl:if> 

只在一個地方定義的變量,但它的價值是有條件的。現在temp的值已設置,它不能在稍後重新定義。在函數式編程中,變量更像只讀參數,因爲它們可以設置,但以後不能更改。爲了在任何函數式編程語言中使用變量,您必須正確理解這一點。

+0

對不起隊友「從XML使用XSLT刪除重複節點」,你的回答是偉大的,但我有改變的問題一點得到它接近我之後。謝謝 – Zoheir 2010-02-05 04:17:29

+5

@Mazzi:總是寫出你想要做的事(輸入 - >想要的輸出)的問題,而不僅僅是*你怎麼認爲你可以做到這一點。在這種情況下:您不想更改變量值,您想要從輸入中生成唯一值列表。 – Tomalak 2010-02-05 09:49:35

+1

+1,_really_偉大的答案,@ Welbog – 2010-02-05 09:56:08

4

試試這個:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="trip" match="trip" use="result" /> 

    <xsl:template match="/trips"> 

    <xsl:for-each select="trip[count(. | key('trip', result)[1]) = 1]"> 
     <xsl:if test="position() != 1">, </xsl:if> 
     <xsl:value-of select="result"/> 
    </xsl:for-each> 

    </xsl:template> 
</xsl:stylesheet>