Monday, April 11, 2011

XSLT: How to represent OR in a "match" attribute?

I want to perform a series of operations on elements that matched the name "A" or "B". I'm thinking of something like this below, but it doesn't work.

<xsl:template match= " 'A' or 'B'" >
     <!-- whatever I want to do here -->
</xsl:template>

Couldn't find the appropriate XSLT language reference for it. Please help! Thanks!!

From stackoverflow
  • Try this:

    <xsl:template match= "A | B" >
    

    See this page for details.

  • The below information was gleaned from: http://www.cafeconleche.org/books/bible2/chapters/ch17.html#d1e2090

    I will paraphrase, please search for the text "Using the or operator |" in that document.

    The syntax is:

    <xsl:template match="A|B">
       <!-- Do your stuff> -->
    </xsl:template>
    
  • Generally A | B is the right way to do this. But the pipe character is basically a union of two complete XPath expressions. It can be annoying to use it in a case like this:

    /red/yellow/blue/green/gold | red/orange/blue/green/gold
    

    since you're repeating the entirety of the expression except for the one small piece of it's that changing.

    In cases like this, it often makes sense to use a predicate and the name() function instead:

    /red/*[name() = 'yellow' or name()='orange']/blue/green/gold
    

    This technique gives you access to a much broader range of logical operations. It's also (conceivably) faster, as the XPath navigator only has to traverse the nodes it's testing once.

  • <xsl:template match= " 'A' or 'B'" >

    There are a few problems with this match pattern:

    1. A template matche nodes, not strings. Therefore, the names of the elements to be matched should not be specified as quoted strings.

    2. The XPath operator "or" acts on two boolean values, not on nodes. What is necessary here is another XPath operator -- the union operator "|".

    Taking into account the above, one will correctly specify the template rule as:

    <xsl:template match= "A | B" >
         <!-- whatever I want to do here -->
    </xsl:template>
    
  • I think it's more convenient to use this XPath

    /red/(yellow | orange)/blue/green/gold
    

    rather than

    /red/*[name() = 'yellow' or name()='orange']/blue/green/gold
    

0 comments:

Post a Comment