简体   繁体   English

从XSLT 2.0中的序列调用命名模板

[英]Call named templates from the sequence in XSLT 2.0

Let's say that I have a sequence of strings. 假设我有一系列字符串。 The strings are actually names of named templates. 字符串实际上是命名模板的名称。 Each of these named templates validates something in the input XML and returns a string. 这些命名模板中的每一个都验证输入XML中的某些内容并返回一个字符串。 If the validation fails, it returns error message, otherwise it returns zero length string (it means that the validation succeeded). 如果验证失败,则返回错误消息,否则返回零长度字符串(表示验证成功)。

I would like to have a template that would iterate through the sequence and call the named templates one after another. 我希望有一个模板可以遍历序列并一个接一个地调用命名模板。 If one of them returned response (error message) that is longer than 0, then it should stop calling the templates and return that error message. 如果其中一个返回的响应(错误消息)长于0,则它应该停止调用模板并返回该错误消息。

I am wondering if this is possible using XSLT 2.0. 我想知道使用XSLT 2.0是否可行。

You can dispatch activity based on a sequence of strings by exploiting the template matching mechanism of XSLT 2 and synthesizing the actions that are then acted on by the push and match. 您可以通过利用XSLT 2的模板匹配机制并合成随后的推送和匹配操作的操作,根据字符串序列调度活动。 This has a similar effect to the call, that is invoking another template, but it is done on demand. 这与调用具有类似的效果,即调用另一个模板,但它是按需完成的。 The transcript below illustrates this: 下面的成绩单说明了这一点:

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>

It is not possible in pure XSLT 1.0 or 2.0, like in many other languages you can't call a template (or function/subroutine/procedure) dynamically. 在纯XSLT 1.0或2.0中,它不可能像许多其他语言一样动态调用模板(或函数/子例程/过程)。 Saxon however offers http://www.saxonica.com/documentation/index.html#!extensions/instructions/call-template . 然而,Saxon提供http://www.saxonica.com/documentation/index.html#!extensions/instructions/call-template

You could make a recursive template processing sequence of strings as a parameter. 您可以将递归模板处理字符串序列作为参数。

In it you could hardcode some (a bit clumsy) xsl:choose evaluating first string in that sequence and in appropriate xsl:when call the appropriate template. 在其中你可以硬编码一些(有点笨拙) xsl:choose评估该序列中的第一个字符串和适当的xsl:when调用适当的模板时。 If it returned no error then call your recursive template again with the rest of strings sequence otherwise do something else. 如果它没有返回任何错误,那么再次使用其余字符串序列调用递归模板,否则执行其他操作。

But it is obvious you had to add new xsl:when every time you added new template to be called and therefore such code could be difficult to maintain. 但很明显你必须添加新的xsl:when你每次添加要调用的新模板时,这样的代码很难维护。

Actually I think the main point of your question is the purpose of your requirement. 实际上我认为你问题的主要观点是你的要求的目的。 Might be you could achieve same goal using more separate stylesheets combined with some pipeline (eg XProc or something similar) 您可以使用更多单独的样式表和一些管道(例如XProc或类似的东西)来实现相同的目标

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM