XSLT: Difference between using predicates and <xsl:if> statement

I am trying to understand if there is any difference between using predicates and using an <xsl:if> ?

From a performance perspective, is the use of a predicate any better? Does predicates also traverse through each node in the xml tree to identify the nodes based on the filter criteria?

2 answers

  • answered 2018-07-12 12:58 kjhughes

    The decision between placing conditionals within XPath predicates or xsl:if (or xsl:when) tests is really one of style, not performance.

    Procedural code can be written in XSLT using loops and if statements, but to leverage the power of XSLT elegantly, base your XSLT upon its declarative pattern matching and transformation capabilities.

    Instead of thinking procedurally (do this; then do that), think about how to declaratively express relationship between input XML and output XML via matching and transforming (match input XML and map to output XML This is the purpose of xs:template.). Predicates help you express pattern matching declaratively and therefore are preferred over procedural xsl:if statements when using XSLT the way it was designed to be used.

  • answered 2018-07-12 13:11 Martin Honnen

    XSLT and XQuery use XPath as an expression language, a predicate is part of an XPath expression https://www.w3.org/TR/xpath-31/#id-filter-expression, an xsl:if is an instruction of the XSLT language https://www.w3.org/TR/xslt-30/#xsl-if.

    For the example you have mentioned in your comment to Tim I would think that most people prefer the compact XPath syntax approach of selecting and filtering with a predicate, unless you need to output the position of the node with name = 'John' in relation to all selected nodes e.g. <xsl:for-each select="person[name = 'John']"><xsl:value-of select="position()"/></xsl:for-each> will output output 1,2,3... for the number of person elements with a name = 'John' child element while <xsl:for-each select="person"><xsl:if test="name = 'John'"><xsl:value-of select="position()"/></xsl:if></xsl:for-each> will output the position of each person element with a name = 'John' child element in the sequence of all person elements.

    As for performance, I think you would need to check that for a particular case with a particular processor, for a declarative language a processor might choose to rewrite or optimize any code as long as it produces the defined output.