2009-07-14 34 views
0

以下工作:XSLT:XSL:功能不會爲我工作

<xsl:variable name="core" select="document('CoreMain_v1.4.0.xsd')" /> 
<xsl:variable name="AcRec" select="document('AcademicRecord_v1.3.0.xsd')" /> 

<xsl:template match="xs:element">  
    <xsl:variable name="prefix" select="substring-before(@type, ':')" /> 
    <xsl:variable name="name" select="substring-after(@type, ':')" /> 

    <xsl:choose> 
    <xsl:when test="$prefix = 'AcRec'">    
     <xsl:apply-templates select="$AcRec//*[@name=$name]"> 
     <xsl:with-param name="prefix" select="$prefix" /> 
     </xsl:apply-templates>     
    </xsl:when> 
    <xsl:when test="$prefix = 'core'">    
     <xsl:apply-templates select="$core//*[@name=$name]"> 
     <xsl:with-param name="prefix" select="$prefix" /> 
     </xsl:apply-templates>     
    </xsl:when>    
    </xsl:choose> 
</xsl:template> 

但是我用同樣的邏輯來處理基於前綴的電流或其他文檔元素的查找,匹配節點名稱在樣式表中的許多地方。因此,改變樣式表的版本到2.0後,我想:

<xsl:template match="xs:element"> 
    <xsl:value-of select="my:lookup(@type)" /> 
</xsl:template> 

<xsl:function name="my:lookup"> 
    <xsl:param name="attribute" /> 

    <!-- parse the attribute for the prefix & name values --> 
    <xsl:variable name="prefix" select="substring-before($attribute, ':')" /> 
    <xsl:variable name="name" select="substring-after($attribute, ':')" /> 

    <!-- Switch statement based on the prefix value --> 
    <xsl:choose> 
    <xsl:when test="$prefix = 'AcRec'">    
     <xsl:apply-templates select="$AcRec//*[@name=$name]"> 
     <xsl:with-param name="prefix" select="$prefix" /> 
     </xsl:apply-templates>     
    </xsl:when> 
    <xsl:when test="$prefix = 'core'">    
     <xsl:apply-templates select="$core//*[@name=$name]"> 
     <xsl:with-param name="prefix" select="$prefix" /> 
     </xsl:apply-templates>     
    </xsl:when>    
    </xsl:choose> 
</xsl:function> 

在我的閱讀,我只發現返回文本的函數的例子 - 沒有呼模板。我有一個印象,一個xsl:函數應該總是返回文本/輸出...

經過更多的調查,它進入my:lookup函數和變量(前綴&名稱)正在填充。所以它會輸入xsl:choose語句,並且在測試時命中適當。問題似乎與apply-templates-value-of顯示的是子值有關; copy-of也一樣,我認爲這很奇怪(不應該輸出包含xml元素聲明?)。如果將模板聲明中的代碼移動到xsl:function,爲什麼會有區別?

+0

哪個XSLT引擎?撒克遜或Xalan或其他什麼?請注意,Xalan不支持XSLT 2.0,但Saxon不支持。 Xalan和Saxon都支持函數,但它們在XSLT 1.0和2.0之間的行爲不同。 – lavinio 2009-07-14 18:43:33

+0

我正在使用撒克遜。 – 2009-07-14 19:02:51

回答

2

這已經有一段時間,因爲我沒有任何嚴重的XSLT,但IIRC你的問題是不是在功能,但在你的模板:

<xsl:template match="xs:element"> 
    <xsl:value-of select="my:lookup(@type)" /> 
</xsl:template> 

value-of語句不會內聯結果樹返回通過你的功能。相反,它會嘗試將結果樹減少爲某種字符串,然後將其內聯。這就是爲什麼你看到孩子的價值觀,而不是自己的元素。

要內嵌函數返回的結果樹,您需要使用一些模板將結果樹複製到位。

所以,你的主模板將需要改變這樣的:

<xsl:template match="xs:element"> 
    <xsl:apply-templates select="my:lookup(@type)" /> 
</xsl:template> 

,你會需要一些模板做遞歸調用。快速谷歌發現a good discussion of the identity template應該做你需要的。

(請原諒任何語法錯誤,正如我所說,它已經有一段時間...)