0

嗨,我是 xslt 的完整初学者,并且刚刚开始使用它,因为我正在使用 Umbraco 构建站点。我想知道是否有任何方法可以在 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 节点我正在重用相同的代码来列出孩子所以我想知道是否可以将其拉出到一个函数中,这样我就不必为我需要的每个级别的孩子嵌套相同的代码

4

2 回答 2

1

XSLT 中的想法是使用与 XML 结构中的某些节点匹配的模板。您甚至可以使用“模式”应用具有不同处理指令的相同模板。

我不知道您的 XML 结构,但我认为这将是要走的路。在 stackoverflow 中搜索也提供了信息:https ://stackoverflow.com/questions/tagged/templates+xslt

于 2013-02-05T10:25:20.780 回答
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 的测试表达式中调用它们例子。

于 2013-02-05T11:27:00.440 回答