具有动态 QName 的 XSLT 调用模板? [英] XSLT call-template with dynamic QName?

查看:27
本文介绍了具有动态 QName 的 XSLT 调用模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我四处寻找解决我的问题的方法,但我还有更多问题...

I have searched all around to find a solution to my problem, but i just got more questions...

考虑以下 XML:

<dynamicStuff>
      <dyn id="name1">...</dyn>
      <dyn id="name2">...</dyn>
      <dyn id="name3">...</dyn>
      <dyn id="name4">...</dyn> 
</dynamicStuff>

假设我有一个 XSLT 文件,如下所示:

and suppose the I have an XSLT file as follows:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

     <xsl:template name="name1">    
         ...
     </xsl:template>

     <xsl:template name="name2">    
         ...
     </xsl:template>

     <xsl:template name="name3">    
         ...
     </xsl:template>

     <xsl:template name="name4">    
         ...
     </xsl:template>

</xsl:stylesheet>

我想要做的是从第二个 XSLT 文件动态确定要调用的模板,如下所示:

What I want to do is from a SECOND XSLT file dynamically determine which template to call with something like this:

<xsl:variable name="templateName">
     <xsl:value-of select="dyn/@id"/>
</xsl:variable>

<xsl:call-template name="$templateName"/>

遗憾的是它不起作用,相信我,当我说我尝试了很多不同的东西时,虽然听起来很简单,但它也不起作用......

sadly its not working, believe me when I say that I have tried a lot of different stuff, though it sounds so simple it does not work either...

我错过了什么吗?

我已成功完成以下操作:

I have successfully done the following:

<xsl:template name="staticName">
    <xsl:param name="id" />

    <xsl:if test="$id = 'name1'">....</xsl:if>
    <xsl:if test="$id = 'name2'">....</xsl:if>
    ...
</xsl:template>

这样调用:

<xsl:call-template name="staticName">
     <xsl:with-param name="id" select="@id"/>
</xsl:call-template>

说这有多不方便……首先,我的代码将绑定到那个 staticName(假设我需要在十几个文件中执行此调用)……其次我将有一堆(un)同一个模板里面的相关内容,当它可以更分离时......升级系统的噩梦uu

Needles to say how inconvenient this is... first of all my code will be bound to that staticName (imagine I need to do this call in a dozen files)... second I will have a bunch of (un)related content inside the same template when it could be more separated... a nightmare to upgrade the system u.u

它做我想要的,但不是我需要的......

It does what I want but not in the way I need...

提前感谢您对此事的任何了解!

Thanks in advance for any light on this matter!

推荐答案

来自 http://www.w3.org/TR/xslt#named-templates

name 属性的值是一个QName,其扩展如[2.4 合格姓名].

The value of the name attribute is a QName, which is expanded as described in [2.4 Qualified Names].

这意味着它既不是表达式也不是 AVT.

It means that is neither an expression nor an AVT.

显式 xsl:call-template 指令无论是逻辑指令还是模式匹配都可以,例如:

Explicit xsl:call-template instructions are fine whether by logic instructions or pattern matching like:

<xsl:template match="dyn[@id='name1']" mode="dynamic">
 <xsl:call-template name="name1"/>
</xsl:template>

另一种方法是命名模板引用...

Another approach is named template references...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="vTemplate" select="document('')/*/xsl:template"/>
    <xsl:template match="dyn">
        <xsl:apply-templates select="$vTemplate[@name = current()/@id]"/>
    </xsl:template>
    <xsl:template match="xsl:template[@name='name1']"
                  name="name1"> one </xsl:template>
    <xsl:template match="xsl:template[@name='name2']"
                  name="name2"> two </xsl:template>
    <xsl:template match="xsl:template[@name='name3']"
                  name="name3"> three </xsl:template>
    <xsl:template match="xsl:template[@name='name4']"
                  name="name4"> four </xsl:template>
</xsl:stylesheet> 

输出:

 one  two  three  four 

<小时>注意: 由于此技术使用 document('') 来处理 XSLT 而不是原始 XML 文件,因此正在处理的原始文档在命名模板中不可用.但是,如果需要,您可以将 current() 作为参数显式传递给模板:


Note: Because this technique uses document('') to process the XSLT rather than the original XML file, the original document being processed is not available in the named templates. However, you can explicitly pass current() as parameter to the templates if needed:

    <xsl:template match="dyn">
        <xsl:apply-templates select="$vTemplate[@name = current()/@id]">
            <xsl:with-param name="current" select="current()"/>
        </xsl:apply-templates>
    </xsl:template>

如果需要,可以使用$current访问原始文档:

If needed, $current can be used to access the original document:

    <xsl:template match="xsl:template[@name='name1']" name="name1">
        <xsl:param name="current"/>
        <xsl:value-of select="$current/@id"/>
        <xsl:text> becomes one</xsl:text> 
    </xsl:template>

如果需要,可以使用 for-each$current 重新建立为当前节点:

If needed, $current could be re-established as current node using for-each:

<xsl:template match="xsl:template[@name='name2']" name="name2">
    <xsl:param name="current"/>
    <xsl:for-each select="$current">
            <xsl:value-of select="@id"/>
            <xsl:text> becomes two</xsl:text>
    </xsl:for-each>
</xsl:template>

这篇关于具有动态 QName 的 XSLT 调用模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆