问题描述
我四处寻找解决我的问题的方法,但我还有更多问题...
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 合格姓名].
这意味着它既不是表达式也不是 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 调用模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!