2015-10-16 61 views
-1

我的xml:如何獲得的祖先軸的屬性在XSLT

<msg id="abc" type="test"> 
    <local id="def"/> 
    <cnts x:type="fld" id="111" type="a2"> 
    </cnts> 
</msg> 

的XSLT是:

<xsl:template match="contents[@x:type='fld']"> 
    <xsl:variable name="msgs"> 
    <xsl:for-each select="ancestoer::msg"> 
     <msg><xsl:value-of select="@type"/></msg> 
    </xsl:for-each> 
    </xsl:variable> 
</xsl:template> 

我期望的輸出將是:

<msg>test</msg> 

但它不能按預期工作。有人可以幫忙嗎?

+1

輸入XML有一個元素'cnts',它與XSLT中的'contents'不同。爲什麼要這麼做?更新XML以完成。有一個變量來存儲一些值不會輸出它,向我們展示您的完整XSLT!而且,這個軸被拼成「祖先」! –

回答

1

有幾個與你的XSLT和你的XML,問題的每一個可能會或可能不會是你的問題的原因:

  1. 你的XSLT是不完整的,你可能這樣做是爲了節省空間,但它更難猜測什麼是錯誤的(名稱空間綁定,應用模板等)
  2. 您的XML與您的XSLT不匹配,如註釋中所述,該模板匹配contents,這不在您的XML中你的意思是cnts?)。
  3. 即使您的代碼段包含在有效的xsl:stylesheet元素中,也無法編譯,ancestoer::msg會引發編譯時(靜態)錯誤。
  4. 您的代碼段定義了一個變量,但沒有使用它,因此無論您的變量中的任何內容都不可見。
  5. 你似乎要循環祖先軸,它可以選擇多個元素msg,不知道這是故意的

如果以上所有都在您的實際XSLT是正確的,那麼你的問題在於別處我們將不得不看到更多的XSLT XML,事實上,我們需要一個Minimal, Complete, and Verifiable example

這就是說,這裏使用的是祖先軸的方式有三種:

  1. 如果你只想要一個項目,你不需要中間變量,你可以簡單地使用<xsl:value-of select="ancestor::msg/@type" />
  2. 如果你想遍歷所有祖先,你可以使用:

    <xsl:template match="contents[@x:type='fld']"> 
        <xsl:apply-templates select="ancestor::msg" mode="anc" /> 
    </xsl:template> 
    
    <xsl:template match="msg" mode="anc"> 
        <msg><xsl:value-of select="@type" /></msg> 
    </xsl:message> 
    

    在這個例子中,我特意切換模式,因爲你可以在msg其他地方已經匹配一個很好的機會,在哪種情況下你最終可能會陷入永無止境的循環。

  3. 您目前的做法與xsl:for-each。這並沒有錯,只是不太靈活,從長遠來看,還有更多的打字。變量的使用不是必需的,但如果你想使用變量,只要確保你也使用它,例如xsl:copy-of
+0

我在最後一刻更改了屬性名稱,並忘記在xslts中更改它。 xslt中的變量確實用在其他地方。感謝答案阿貝爾! – dellair