xslt遍历整个列表或直到匹配

时间:2018-01-17 13:40:00

标签: xml xslt watson-explorer

我需要迭代一个对象列表并在xslt中对它们进行比较。如果找到匹配项,我需要停止处理该文档。如果我到达列表的末尾并且未找到匹配项,那么我需要处理该文档。 问题是xslt变量一旦声明就无法更改。这将是一个简单的For循环,在其他常见语言中使用true / false变量。

     <!--I need to iterate through this list-->
        <xsl:variable name="exclude">
          <exclude block="999" />
          <exclude block="111" />
        </xsl:variable>

        <xsl:template match="@*|node()">
          <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
          </xsl:copy>
        </xsl:template>

<!-- Here I iterate through the docs, but I don't iterate though the objects in the list.The main problem is I don't know how to search the list and make a decision at the end or when I encounter a match. This code only works on the first object "999" -->
        <xsl:template match="/">
          <xsl:if test="not(contains($url, exsl:node-set($exclude)/exclude/@block))">
            <xsl:copy-of select="." />
          </xsl:if>
        </xsl:template>

3 个答案:

答案 0 :(得分:0)

如果您正在使用XSLT 2.0,您可以在模板或函数中使用尾端递归,理想情况下使用主要的select-when-otherwise构造(when语句提供终止机制,否则准备下一个循环和调用本身)。

如果您使用的是3.0,请尝试使用xsl:iterate

答案 1 :(得分:0)

您还没有显示输入文档,也没有设置变量以及您想要检查的内容但我认为您不需要任何迭代,如果您不想检查{ {1}}属性值包含在您的变量

block

足以做到这一点。

我已经把三个样本放在

  1. http://xsltfiddle.liberty-development.net/3Nqn5Y9
  2. http://xsltfiddle.liberty-development.net/3Nqn5Y9/1
  3. http://xsltfiddle.liberty-development.net/3Nqn5Y9/2
  4. 前两个匹配(参数<xsl:if test="not(exsl:node-set($exclude)/exclude/@block[contains($url, .)])"> 分别是url <xsl:param name="url">file://111</xsl:param>)并且没有创建输出,最后一个匹配(<xsl:param name="url">file://999</xsl:param>)和输出已创建。

    因此,至少在正常XSLT 1设置的上下文中使用变量或参数,如图所示,该方法有效。

答案 2 :(得分:0)

这里有很多可能的策略。

通常,可以编写一个路径表达式来选择要处理的项目,并在xsl:for-each的select属性中使用它。

不起作用的情况是一个项目的处理(或终止的决定)取决于为先前项目计算的信息(以及每次重复计算的成本太高)。

在这种情况下,经典的解决方案是使用头尾递归:编写一个模板或函数,将项列表作为参数。模板/函数必须(a)决定是否继续处理(通常在输入列表为空时退出,但可能有其他终止条件),(b)处理第一个(“head”)项,以及(c)调用本身递归地处理列表的其余部分(“尾部”)。

在XSLT 3.0中有一个名为xsl:iterate的便捷指令,许多人发现这种指令更容易使用递归,因为它看起来更像传统的程序编程。它就像xsl:for-each,除了执行是严格顺序的,并且在处理了一个项目后,你设置了处理下一个项目时可用的参数;并且有一个xsl:break指令提前退出。

最后,在3.0中,您可以使用更高级别的左侧或右侧折叠功能的函数式编程方法。除非你从其他函数式编程语言来到XSLT,否则这可能不是你的首选。此外,它始终处理整个输入序列:没有提前退出的选项。