Search code examples
xmlxsltwatson-explorer

xslt iterate through a whole list or until match


I need to iterate through a list of objects and compare them in xslt. If a match is found I need to stop processing the document. If I get to the end of the list and no match is found then I need to process the document. The problem is xslt variables can't be changed once they are declared. This would be a simple For loop with a true/false variable in other common languages.

     <!--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>

Solution

  • You haven't shown the input document nor how you set up the variable and what exactly you want to check but I don't think you need any iteration, if you want to check that none of the block attribute values is contained in your variable then

    <xsl:if test="not(exsl:node-set($exclude)/exclude/@block[contains($url, .)])">
    

    suffices to do that.

    I have put three samples up at

    1. http://xsltfiddle.liberty-development.net/3Nqn5Y9
    2. http://xsltfiddle.liberty-development.net/3Nqn5Y9/1
    3. http://xsltfiddle.liberty-development.net/3Nqn5Y9/2

    the first two match (parameter url is <xsl:param name="url">file://111</xsl:param> respectively <xsl:param name="url">file://999</xsl:param>) and no output is created, the last doesn't match (<xsl:param name="url">file://888</xsl:param>) and the output is created.

    So at least in the context of a normal XSLT 1 setting with the variable or parameter as shown the approach works.