2010-03-15 44 views
3

我想通過使用xsl:foreach的xml文檔進行迭代,但我需要select =「」纔是動態的,所以我使用變量作爲源。以下是我已經試過:在xsl:foreach select語句中使用xsl:變量

...

<xsl:template name="SetDataPath"> 
    <xsl:param name="Type" /> 

    <xsl:variable name="Path_1">/Rating/Path1/*</xsl:variable> 
    <xsl:variable name="Path_2">/Rating/Path2/*</xsl:variable> 

    <xsl:if test="$Type='1'"> 
    <xsl:value-of select="$Path_1"/> 
    </xsl:if> 

    <xsl:if test="$Type='2'"> 
    <xsl:value-of select="$Path_2"/> 
    </xsl:if> 
<xsl:template> 

...

<!-- Set Data Path according to Type --> 
    <xsl:variable name="DataPath"> 
    <xsl:call-template name="SetDataPath"> 
     <xsl:with-param name="Type" select="/Rating/Type" /> 
    </xsl:call-template> 
    </xsl:variable> 

...

<xsl:for-each select="$DataPath"> 

...

在foreach拋出一個錯誤,指出:「XslTransformException - 要使用一個路徑表達式中的結果樹片段,首先使用msxsl:node-set()函數將其轉換爲節點集。「

但是,當我使用msxsl:node-set()函數時,我的結果爲空。

我知道我將$ DataPath設置爲一個字符串,但不應該從node-set()函數創建節點集嗎?我錯過了什麼嗎?當我不使用變量時:

<xsl:for-each select="/Rating/Path1/*"> 

我得到了正確的結果。

下面是我使用的XML數據文件:

<Rating> 
    <Type>1</Type> 
    <Path1> 
     <sarah> 
      <dob>1-3-86</dob> 
      <user>Sarah</user> 
     </sarah> 
     <joe> 
      <dob>11-12-85</dob> 
      <user>Joe</user> 
     </joe> 
    </Path1> 
    <Path2> 
     <jeff> 
      <dob>11-3-84</dob> 
      <user>Jeff</user> 
     </jeff> 
     <shawn> 
      <dob>3-5-81</dob> 
      <user>Shawn</user> 
     </shawn> 
    </Path2> 
</Rating> 

我的問題很簡單,你怎麼跑2條不同路徑的foreach?

+0

很難在不說至少看到一個XML片段。 – Oded 2010-03-15 17:15:20

回答

3

試試這個:

<xsl:for-each select="/Rating[Type='1']/Path1/* 
         | 
          /Rating[Type='2']/Path2/*"> 
+0

這是我一直在尋找的精確解決方案,非常感謝!優雅和有效= D – Nefariousity 2010-03-16 15:02:44

0

您提到的node-set()函數可以將結果樹片段轉換爲節點集,這是正確的。但是:您的XSLT不會生成結果樹片段。

您的模板SetDataPath會生成一個字符串,然後將其存儲到變量$DataPath中。當您執行<xsl:for-each select="$DataPath">時,XSLT處理器扼殺了DataPath不包含節點集但是包含字符串的事實。

您的整個樣式表似乎圍繞着動態選擇/評估XPath表達式的想法。放棄這個想法,這是既不可能也不必要的。

顯示您的XML輸入並指定想要執行的轉換,然後我可以嘗試向您顯示一種方法。

+0

感謝您的幫助。我添加了我正在使用的XML數據。那麼如何在同一個foreach語句中使用2個不同的路徑呢? – Nefariousity 2010-03-15 18:23:42

+0

@危險性:不,你的問題不是「你如何在兩條不同的路徑上運行foreach?」,因爲這是你試圖實現的解決方案。說明你的問題*,而不是你想要解決的問題。 – Tomalak 2010-03-15 19:11:31

+0

如我的XML文件所示,我在2個不同的路徑中具有相同的屬性。我如何在foreach循環中訪問這些屬性,而不必將循環複製兩次到兩個不同的if語句中? – Nefariousity 2010-03-15 19:38:42

3

標準XSLT 1.0不支持的XPath的動態評估。但是,您可以通過重組解決方案來調用一個命名模板,傳遞你想處理作爲參數的節點集實現你想要的結果:

<xsl:variable name="Type" select="/Rating/Type"/> 
<xsl:choose> 
    <xsl:when test="$Type='1'"> 
     <xsl:call-template name="DoStuff"> 
      <xsl:with-param name="Input" select="/Rating/Path1/*"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:when test="$Type='2'"> 
     <xsl:call-template name="DoStuff"> 
      <xsl:with-param name="Input" select="/Rating/Path2/*"/> 
     </xsl:call-template> 
    </xsl:when> 
</xsl:choose> 

...

<xsl:template name="DoStuff"> 
    <xsl:param name="Input"/> 
    <xsl:for-each select="$Input"> 
     <!-- Do stuff with input --> 
    </xsl:for-each> 
</xsl:template> 
+0

這很好,非常感謝幫助= D – Nefariousity 2010-03-16 14:53:23

相關問題