【问题标题】:XSLT Call-Template name attributeXSLT 调用模板名称属性
【发布时间】:2011-12-02 21:29:28
【问题描述】:

似乎我不能在 call-template 元素的 name 属性中使用 Xpath。我怎样才能解决这个问题?任何帮助/想法都会很棒!

<xsl:for-each select="child::knomaddb/Content/Videos">
        <xsl:result-document method="xhtml" href="{local-name()}.html">
            <html>
                <body>
                    <h1>Knomad</h1>
                    <h2>{local-name()} Videos</h2>
                    <table border="1">
                        <tr bgcolor="#9acd32">
                            <th>Title</th>
                            <th>Video</th>
                            <th>Description</th>
                            <th>Comments</th>
                        </tr>
                        <xsl:for-each select="Video">
                            <xsl:call-template name="{ancestor::local-name()}"/>
                        </xsl:for-each>
                    </table>
                </body>
            </html>
        </xsl:result-document>
    </xsl:for-each>

【问题讨论】:

  • 您是否尝试过使用应用模板和模板规则来解决您的问题? call-template 指令不接受名称属性中的 xpath 表达式,您必须显式设置名称。
  • 除了您似乎在尝试重新发明 xsl:apply-templates 之外,您的 XPath 表达式祖先::local-name() 不是有效的 XPath 表达式,如果它是的话可能选择多个名称,因为一个节点有多个祖先。

标签: xml xslt xpath xslt-2.0


【解决方案1】:

好像我不能在名称属性中使用 Xpath 调用模板元素。我该如何解决这个问题?

好问题,+1。

你不能。但你可以改用&lt;xsl:apply-templates&gt;

这是一个快速演示:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:double="double" xmlns:incr="incr" xmlns:my="my:my"
exclude-result-prefixes="double incr my"
>
  <xsl:output method="text"/>

   <double:double/>
   <incr:incr/>

   <xsl:variable name="vFuncDouble"
        select="document('')/*/double:*[1]"/>

   <xsl:variable name="vFuncIncr"
        select="document('')/*/incr:*[1]"/>

   <xsl:function name="my:double">
     <xsl:param name="arg1" />

      <xsl:sequence select="2*$arg1"/>
   </xsl:function>

   <xsl:function name="my:incr">
     <xsl:param name="arg1" />

      <xsl:sequence select="1+$arg1"/>
   </xsl:function>

    <xsl:template name="double" match="double:*">
      <xsl:param name="arg1"/>

      <xsl:sequence select="my:double($arg1)"/>
    </xsl:template>

    <xsl:template name="incr" match="incr:*">
      <xsl:param name="arg1"/>

      <xsl:sequence select="my:incr($arg1)"/>
    </xsl:template>

    <xsl:function name="my:apply">
      <xsl:param name="pFun" as="element()"/>
      <xsl:param name="arg1"/>

      <xsl:apply-templates select="$pFun">
        <xsl:with-param name="arg1" select="$arg1"/>
      </xsl:apply-templates>
    </xsl:function>

    <xsl:template match="/">
     <xsl:sequence select="my:apply($vFuncIncr, my:apply($vFuncDouble,2))"/>
    </xsl:template>
</xsl:stylesheet>

当此转换应用于任何 XML 文档(未使用)时,会产生所需的结果:

5

请注意

可以将作为参数(第一个参数)传递给 my:apply() 任何“函数”, my:apply() 会将其应用于第二个参数

使用相同的原理 the FXSL library 在 XSLT 1.0 和 XSLT 2.0 中实现了高阶函数 (HOF) -- read more here

在即将推出的 XPath 3.0 中,函数首次成为 Xpath Data Model (XDM) 中的第一类对象。

【讨论】:

    【解决方案2】:

    这是设计使然。 xsl:call-templatedefined as follows

    <!-- Category: instruction -->
    <xsl:call-template
      name = qname>
      <!-- Content: xsl:with-param* -->
    </xsl:call-template>
    

    name 属性必须是 qualified name,而不是 XPath 表达式。

    来源:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 2014-03-22
      • 1970-01-01
      相关资源
      最近更新 更多