Logical AND and OR

1. Logical AND and OR functionality


Logical AND and OR functionality

Mike Brown

> I often visit tutorial-sites to get my informations (and now this great
> mail-list) and there was no "and", only a | for or.

"|" never really means "or".

In an XSLT pattern, which is what goes in a "match" attribute, it's just a separator between node tests when used in a pattern. Depending on how you like to interpret your code into English, you might use the words "or" or "and" informally.

For example, <xsl:template match="foo|bar"> says this template is a good match for a node that matches the test foo (element named foo in no namespace), and it is also a good match for a node that matches the test bar (element named bar in no namespace). Since a programmer might be used to reading "|" as "or", it would be just as correct to say "this template is a good match for a foo or a bar".

In an XPath expression, "|" is a set union operator.

In mathematics, a set is an unordered group of values, typically written (in math, not XPath) as a comma-separated list inside curly braces: {1,2,3,4}. Order doesn't matter. The union of two sets is the result of merging them and eliminating duplicates. The union of {1,2,3,4} and {2,3,5} is {1,2,3,4,5}.

In XPath, it works the same way with nodes. select="foo|bar" means to use the union of the node-set {all child::foo elements} and the node-set {all child::bar elements}, producing the node-set.

Note that I'm mixing notations here; there are no curly braces in XPath, and in XSLT they are only used in XSLT Attribute Value Templates to delimit XPath expressions embedded in literal attribute values.

Wendell Piez adds

As a footnote to what Mike B. says about "|": strictly speaking it's the union operator even when appearing in match patterns. This makes sense if you think about match patterns in the way the spec describes:

"A node matches a pattern if the node is a member of the result of evaluating the pattern as an expression with respect to some possible context; the possible contexts are those whose context node is the node being matched or one of its ancestors" [XSLT 5.2]

Admittedly that's more than a mouthful: but it makes sense if you think about it that the union operator could be used in such a context to get an effective "match this node *or* this other node". Note that the Boolean "or" is not so useful (and in fact the spec has just stipulated that "An expression that is also a pattern always evaluates to an object of type node-set", and an "or" operator always evaluates to a Boolean).

What's worse (or better :-): in practice, the union operator and the "or" operator can give effectively the same results, as in select="*[red|green]" vs. select="*[red or green]". In the first case, an element "*" is selected if the node set of "child::red|child::green" (union of red children and green children) evaluates to Boolean true() for that element, which is the case if this set contains any members (which will be so if the element has either any red element *or* any green element children). In the second, an element "*" is selected if the node set containing red children is evaluated as Boolean true() (i.e. there are any red children) *or* if the node set containing green children is evaluated as Boolean true(). (I guess the mathematicians can say whether this is some distributive property or what.)

While this is nice, it's also understandable why it's easy to get mixed up about what's really going on with "|". It's not really an "or" at all.

Summary: Vertical bar | acts not unlike an OR function lower case and is the logical AND function