2013-02-05 77 views
0

嗨我是一個完整的初學者與xslt,並剛剛開始使用它,因爲我正在與Umbraco建立一個網站。我想知道是否有任何方法在xslt中創建函數,所以我不必重複相同的事情。我有一個看看幾個網站,但並不真正瞭解它xslt函數來停止重複代碼

我的代碼是:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]> 
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxml="urn:schemas-microsoft-com:xslt" 
    xmlns:umbraco.library="urn:umbraco.library" 
    exclude-result-prefixes="msxml umbraco.library"> 

<xsl:output method="xml" omit-xml-declaration="yes"/> 

<xsl:param name="currentPage"/> 

<xsl:template match="/"> 

<xsl:variable name="items" select="$currentPage/ancestor-or-self::* [@isDoc and @level = 1]/* [@isDoc and string(umbracoNaviHide) != '1']"/> 

<!-- The fun starts here --> 

<xsl:if test="count($items) &gt; 0"> 
<ul id="SubNav" class="level{@level}"> 
    <xsl:for-each select="$items"> 
    <li> 
    <a href="{umbraco.library:NiceUrl(@id)}"> 
     <xsl:value-of select="@nodeName"/> 
    </a> 
    <xsl:if test="count(./child::*[@isDoc and string(umbracoNaviHide) != '1']) &gt; 0"> 
     <ul class="level{@level}"> 
     <xsl:for-each select="./child::*[@isDoc and string(umbracoNaviHide) != '1']"> 
      <li> 
      <a href="{umbraco.library:NiceUrl(@id)}"> 
       <xsl:value-of select="@nodeName"/> 
      </a> 
      <xsl:if test="count(./child::*[@isDoc and string(umbracoNaviHide) != '1']) &gt; 0"> 
       <ul class="level{@level}"> 
       <xsl:for-each select="./child::*[@isDoc and string(umbracoNaviHide) != '1']"> 
        <li> 
        <a href="{umbraco.library:NiceUrl(@id)}"> 
         <xsl:value-of select="@nodeName"/> 
        </a> 
        </li> 
       </xsl:for-each> 
       </ul> 
      </xsl:if> 
      </li> 
     </xsl:for-each> 
     </ul> 
    </xsl:if> 
    </li> 
    </xsl:for-each> 
</ul> 
</xsl:if> 

</xsl:template> 

</xsl:stylesheet> 

正如你所看到的foreach節點,我重複使用相同的代碼列出的孩子,所以我想知道我是否可以將此功能拉到一個功能中,這樣我就不必爲每個需要的兒童層次嵌套相同的代碼

回答

1

XSLT中的想法是使用匹配XML結構中某些節點的模板。您甚至可以使用「模式」將不同的處理指令應用於相同的確切模板。

我不知道你的XML結構,但我認爲這將是一段路要走。在搜索計算器也提供信息:https://stackoverflow.com/questions/tagged/templates+xslt

最好的問候, 彼得

+0

感謝這些信息,我能夠弄清楚我需要另一個模板,並從中獲得瞭解決方案 – Pete

+0

@Pete:您好!即聽起來不錯。很高興我能幫上忙。最好的問候,彼得 – Peter

0

XSLT 2.0允許你寫的,你可以從你的代碼中的XPath表達式調用功能。例如,你可以定義

<xsl:function name="f:isRelevant" as="xs:boolean"> 
    <xsl:param name="node" as="element()"/> 
    <xsl:sequence 
    select="count($node/child::*[@isDoc and string(umbracoNaviHide) != '1'])"/> 
</xsl:function> 

,然後你可以寫,例如

<xsl:if test="f:isRelevant(.)">...</xsl:if> 

如果你是限制你XSLT 1.0的平臺上,那麼你將不得不忍受你的代碼更加冗長。您可以使用命名模板和xsl:call-template指令來處理常見的XSLT代碼塊,但它們幾乎不像函數那樣方便,例如,您不能在xsl的測試表達式中調用它們:if as this in this例。