假设我有一系列字符串。字符串实际上是命名模板的名称。这些命名模板中的每一个都验证输入XML中的某些内容并返回一个字符串。如果验证失败,则返回错误消息,否则返回零长度字符串(表示验证成功)。
我希望有一个模板可以遍历序列并一个接一个地调用命名模板。如果其中一个返回的响应(错误消息)长于0,则它应该停止调用模板并返回该错误消息。
我想知道使用XSLT 2.0是否可行。
答案 0 :(得分:3)
您可以通过利用XSLT 2的模板匹配机制并合成随后的推送和匹配操作的操作,根据字符串序列调度活动。这与调用具有类似的效果,即调用另一个模板,但它是按需完成的。下面的成绩单说明了这一点:
t:\ftemp>type dispatch.xml
<?xml version="1.0" encoding="UTF-8"?>
<doc>Data file</doc>
t:\ftemp>type dispatch.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsd"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:variable name="requirements" select="'this','that','other','that'"/>
<xsl:variable name="data" select="."/>
<xsl:for-each select="$requirements">
<xsl:variable name="action" as="element()">
<xsl:element name="{.}"/>
</xsl:variable>
<xsl:apply-templates select="$action" mode="dispatch">
<xsl:with-param name="data" select="$data"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="this" mode="dispatch">
<xsl:param name="data"/>
<xsl:for-each select="$data">
Doing this with the data: <xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="that" mode="dispatch">
<xsl:param name="data"/>
<xsl:for-each select="$data">
Doing that with the data: <xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="other" mode="dispatch">
<xsl:param name="data"/>
<xsl:for-each select="$data">
Doing the other with the data: <xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>xslt2 dispatch.xml dispatch.xsl
<?xml version="1.0" encoding="UTF-8"?>
Doing this with the data: Data file
Doing that with the data: Data file
Doing the other with the data: Data file
Doing that with the data: Data file
t:\ftemp>
答案 1 :(得分:1)
在纯XSLT 1.0或2.0中不可能像许多其他语言一样动态调用模板(或函数/子例程/过程)。然而撒克逊提供http://www.saxonica.com/documentation/index.html#!extensions/instructions/call-template。
答案 2 :(得分:0)
您可以将递归模板处理字符串序列作为参数。
在其中你可以硬编码一些(有点笨拙)xsl:choose
评估该序列中的第一个字符串,并在适当的xsl:when
中调用适当的模板。如果它没有返回任何错误,那么再次使用其余字符串序列调用递归模板,否则执行其他操作。
但很明显,每次添加要调用的新模板时都必须添加新的xsl:when
,因此这些代码很难维护。
实际上我认为你问题的要点是你的要求的目的。您可以使用更多单独的样式表和一些管道(例如XProc或类似的东西)来实现相同的目标