如何打破每个循环的XSLT?

时间:2014-06-16 12:31:51

标签: xslt xslt-1.0

我知道在XSLT for-each循环中无法中断。 但是从下面的例子中,如果我想要显示'某事'元素是否存在。然后我将通过循环,一旦我得到它,我想打破循环。

  1. 我将制作一个bool变量,例如isExist = false;
  2. 我将逐个浏览所有节点。
  3. 一旦我得到'某事',我会将其值更改为isExist = true
  4. 想在这里打破循环。
  5. 现在我想打破循环bcoz我想将状态显示为true或false。但是如果我不会在第3步之后使用break,它将循环并将其更改为false并且我将获得状态为false。

    我的问题是:如果无法休息那么如何实现这个结果?

    我正在关注此链接How to interrupt an XSLT for-each loop for not contiguos elements?

    根据这个链接,我会先出现两次,但它不会说“有什么”存在。

    <root>
      <item/>
      <item/>
      <something/>
      <item/>
    </root>
    

3 个答案:

答案 0 :(得分:3)

如果你所追求的只是<something/>是否存在,你也可以使用

进行检查
<xsl:if test="/root/something">
    // do fancy stuff...
</xsl:if>

答案 1 :(得分:2)

不是变量在XSLT中如何工作 - 变量总是在词法上限定为包含元素,一旦设置它们就无法更改。

你需要学会更多地以声明方式而不是程序性地思考 - 告诉处理器你希望它找到什么而不是你将如何找到它。 XPath表达式boolean(/root/something)将为您提供所需内容 - 如果something元素作为root的子元素,则为true,否则为false。

答案 2 :(得分:2)

编写与元素选择器匹配的XSLT模板时,例如:

<xsl:template match="entry"> .... </entry>

你有一个像这样的XML文件:

<entries>
    <entry number="345" type="A"/>
    <entry number="123" type="B"/>
    <entry number="334" type="A"/>
    <entry number="322" type="C"/>
</entries>

将为所有entry元素处理的XSLT模板。因此大多数情况下,您永远不需要在XSLT中使用for-each。在上面的示例中,模板将被处理4次,因为有4个entry元素要匹配。在每个内部,您可以提取或打印该上下文中可用的数据(例如,在此示例中为属性)。

您通常也可以在不使用<xsl:if><xsl:choose>的情况下执行许多条件表达式,方法是通过XPath谓词来限制所需的内容。

如果使用这样的谓词为entry元素添加另一个模板:

<xsl:template match="entry[@type='A']"> .... </entry>

然后它覆盖 entry模板,其中entry元素的type属性值为A < / em>的。其他人将由没有谓词的模板处理。

优先使用这些工具,而不是for-eachifchoose,将帮助您以更加面向功能的方式进行思考,并了解如何更好地使用XSLT。

由于变量 params 无法更改,因此您无法使用常规for循环来递增或递减它,但如果您需要, 可以编写一个for循环来增加XSLT 1.0中的变量,但必须以递归方式完成(使用xsl:call-template)。在此策略中,您不为变量分配不同的值,而是在变量块中执行操作,这将设置该变量的最终值。

例如,请参阅此样式表,该样式表计算数字的阶乘。每次递归中的参数 n 都有一个 final 值,该值不会改变,但会在下一次递归中用作另一个 n 参数的数据:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text"/>

    <xsl:param name="number">5</xsl:param>

    <xsl:template match="/">
        <xsl:variable name="fac">
            <xsl:call-template name="factorial">
                <xsl:with-param name="n" select="$number"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$fac"/>
    </xsl:template>

    <xsl:template name="factorial">
        <xsl:param name="n"/>
        <xsl:choose>
            <xsl:when test="$n &gt; 1">
                <xsl:call-template name="factorial">
                    <xsl:with-param name="n-1"/>
                </xsl:call-template>
                <xsl:value-of select="$n * $n - 1"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="1"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>