2013-04-08 52 views
0

我對XSL有點新穎,並且遇到一些問題。根據我的研究,如果在頂層聲明XSL變量<xsl:variable>是全局變量,如果在模板中聲明XSL變量<xsl:variable>,並且您不能更改該值。那麼這是否意味着無法聲明全局變量,然後在模板中更改其值?XSL中的變量

我有以下的情況,我在結果集中迭代,我有一些看起來像這樣:

<xsl:for-each select="NewDataSet/Table1"> 
<xsl:if test="position()= 1"> 
    <xsl:value-of select="SchoolName"/> 
</xsl:if> 

<xsl:if test="position()= 2"> 
    <xsl:value-of select="gender"/> 
</xsl:if> 

<xsl:if test="position() = last()"> 
    <div onclick="showTallyBySchool(,'{SchoolName}','{gender}')"> 
    <xsl:value-of select="node()"/> 
    </div> 
</xsl:if> 
</xsl:for-each> 

正如你看到的,我所需要的值在「性別」和「schoolname」迭代期間第三個'如果'。如果我無法存儲它們,我將如何訪問它們?

編輯:修正了一些錯別字,這裏是從XML摘錄是否有幫助:

<NewDataSet> 
<Table1> 
    <SchoolName>Unknown School</SchoolName> 
    <Gender>Male</Gender> 
    <PS>0</PS> 
    <PK>0</PK> 
    <K>0</K> 
</Table1> 
</NewDataSet> 
+0

請包含相應的XML代碼段和所需的輸出。 – Tomalak 2013-04-08 15:15:30

回答

2

你訪問這些相對當前節點。

我想你已經對你的XML結構感到困惑。例如,您從中選擇SchoolName,但第一個Table1。但代碼會像這樣。

<xsl:for-each select="NewDataSet/Table1[last()]"> 

    <xsl:variable name="school_name" select="../Table1[1]/SchoolName"/> 
    <xsl:variable name="gender" select="../Table1[2]/gender"/> 

    <div onclick="showTallyBySchool(,'{$school_name}',{$gender})"> 
    <xsl:value-of select="node()"/> 
    </div> 

</xsl:for-each> 

請出示你的目標XML數據。我相信有更好的解決方案。

0

首先,您確定XSL中的「變量」在賦值後無法更改。對於變換的執行,它只是「可變的」(即它對於不同的輸入可能以不同的值結束),但在變換內不是「可變的」。其次,從你的例子看來,你仍然在考慮命令式的代碼。您還沒有給予足夠的細節說清楚,但它聽起來像是你有一個SQL型表中的XML文檔,其中

SchoolName is in column 1 
Gender is in column 2 

還可以看出你在Table1要素數據本身,而不是內的元素。

一個寫這將是

<!-- tells what to do at the top level --> 
<xsl:template match="/NewDataSet"> 
    <!-- This means, process child elements according to the templates I define --> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="Table1"> 
    <!-- You should use the exact element names if they are known, couldn't tell from example --> 
    <xsl:variable name="SchoolName" select="*[1]"/> 
    <xsl:variable name="Gender"  select="*[2]"/> 

    <div onclick="showTallyBySchool(,'{$SchoolName}',{$Gender})"> 
     <!-- it's not clear what you want here, but it's probably not this --> 
     <xsl:value-of select="node()"/> 
    </div> 

</xsl:template> 
+0

不推薦使用空模板覆蓋默認規則。我認爲這是在腳下射擊自己。 – Tomalak 2013-04-08 15:20:44

+0

啊!那麼沒有'SchoolName'和'gender'元素?我想你是正確的。讓我們拭目以待,看看OP是否想告訴我們! – Borodin 2013-04-08 15:22:36

+0

@Tomalak,我根據你的建議刪除了這部分,因爲它應該沒有任何區別。在很多情況下,我不太確定輸入格式是否會改變(我只想選擇明確要求的內容),我更喜歡這種用法。我可能從Novatchev先生那裏找到了答案,他通常在答案中包含它。但既然你也是XSL大師,我不得不重新考慮。 – harpo 2013-04-08 15:26:35

0

如果在頂層聲明的XSL變量是全球性的,局部的,如果它的模板內聲明更地道的方式,

不,XSL變量的範圍對包含它的XSLT元素非常嚴格。如果你在<xsl:if>中聲明它,它將在相應的</xsl:if>之後不可用。

並且您無法更改該值。

沒錯,所有XSLT變量都是不可變的。

那麼這是否意味着無法聲明全局變量,然後在模板內更改其值?

正確,你應該永遠不需要。作爲一般規則:如果您發現自己試圖在XSLT中更改變量值,那麼您對問題的處理方法是錯誤的。


正如你看到的,我需要在第三個「如果」期間迭代「性別」和「schoolname」的值。如果我無法存儲它們,我將如何訪問它們?

有了您的XML ...

<NewDataSet> 
    <Table1> 
    <SchoolName>Unknown School</SchoolName> 
    <Gender>Male</Gender> 
    <PS>0</PS> 
    <PK>0</PK> 
    <K>0</K> 
    </Table1> 
</NewDataSet> 

...該解決方案是非常容易的。你根本不需要任何變量。只需直接訪問XML節點<SchoolName><Gender>

<xsl:template match="NewDataSet"> 
    <xsl:apply-templates select="Table1" /> 
</xsl:template> 

<xsl:template match="Table1"> 
    <div> 
    <xsl:value-of select="SchoolName" /> 
    </div> 
    <div> 
    <xsl:value-of select="Gender" /> 
    </div> 
    <div onclick="showTallyBySchool('{SchoolName}', {Gender})"> 
    <xsl:text>Show Tally</xsl:text> 
    </div> 
</xsl:template> 

雖然通常我會建議寧可不要混用HMTL和JavaScript,以及尤其不產生與XSLT的JavaScript。這隻會變得醜陋。

想象一下包含單引號的<SchoolName>。通過上述設置,您已經破壞了您的事件處理程序。

另外,使用內聯事件處理程序像onclick違反關注(標記在這種情況下頁面邏輯)分離的原則,產生難看的HTML和手段,在這種情況下,你需要真正改變你的XSLT文件,當您想要修復JavaScript中的錯誤。它可能具有其他含義,比如與現代JS框架不兼容(即使是內存泄漏,儘管現在這種情況不太常見) - 總之,它通常被忽視。最好將所有JavaScript保存在一個單獨的文件中。