1

假设我有一个字符串序列。字符串实际上是命名模板的名称。这些命名模板中的每一个都验证输入 XML 中的某些内容并返回一个字符串。如果验证失败,则返回错误信息,否则返回零长度字符串(表示验证成功)。

我想要一个模板,它可以遍历序列并一个接一个地调用命名模板。如果其中一个返回的响应(错误消息)长于 0,那么它应该停止调用模板并返回该错误消息。

我想知道这是否可以使用 XSLT 2.0。

4

3 回答 3

4

您可以通过利用 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>
于 2013-09-26T13:38:33.437 回答
1

这在纯 XSLT 1.0 或 2.0 中是不可能的,就像在许多其他语言中您不能动态调用模板(或函数/子例程/过程)一样。但是,Saxon 提供http://www.saxonica.com/documentation/index.html#!extensions/instructions/call-template

于 2013-09-26T09:20:45.460 回答
0

您可以将字符串的递归模板处理序列作为参数。

在其中,您可以硬编码一些(有点笨拙)xsl:choose评估该序列中的第一个字符串并适当地xsl:when调用适当的模板。如果它没有返回错误,则使用其余的字符串序列再次调用您的递归模板,否则执行其他操作。

但很明显,xsl:when每次添加要调用的新模板时都必须添加新模板,因此此类代码可能难以维护。

其实我认为你问题的重点是你要求的目的。可能您可以使用更多单独的样式表和一些管道(例如XProc或类似的东西)来实现相同的目标

于 2013-09-26T09:43:05.117 回答