I have been working with xslt recently, and I have been having trouble understanding the difference between | and or and when I should use which. I understand I can just use the error messages to figure out which one I need to be using but I am interested in learning why I can't use one or the other.
Would anyone be able to help point me in the right direction to someplace where I can learn the difference?
| is concerned with nodes, or is concerned with "truth", that is, Boolean values.
Explanation
The | or union operator
This operator returns the union of two sequences that, in this case, are interpreted as two sets of nodes. An interesting detail is that the union operator removes any duplicate nodes. Also, it only accepts operands of the type node()*, i.e. a sequence of nodes. The nodes are returned in document order.
The or operator
The technical term for this operator is Boolean Disjunction. It takes two arguments, both of which must evaluate to a Boolean value ("true" or "false") individually. Or, more precisely, the operands of or are jugded by their effective Boolean value by converting them to xs:boolean. All of this also applies to the and operator, by the way.
Examples
Use the union operator to enlarge a set of nodes, typically in a template match:
<xsl:template match="Root|Jon">
Why not use the or operator here? Because the match attribute expects a set of nodes as its value. union returns a set of nodes, whereas the or operator returns a Boolean value. You cannot define a template match for a Boolean.
Use the or operator to implement alternatives in XSLT code, mainly using xsl:if or xsl:choose:
<xsl:if test="$var lt 354 or $var gt 5647">
If any of the two operands of this or operation evaluates to true, then the content of xsl:if will be evaluated, too. But not only comparisons like "less than" (lt) have a Boolean value, the following is also perfectly legal:
<xsl:if test="$var1 or $var2">
The above expression only evaluates to true if at least one of the two variables is a non-empty sequence. This is because an empty sequence is defined to have the effective Boolean value of false.
Coercion
Note that because of the way XSLT coerces things to appropriate types, there are some contexts where either operator can be used. Consider these two conditionals:
<xsl:if test="Root | Jon"> ... <xsl:if>
<xsl:if test="Root or Jon"> ... <xsl:if>
The first conditional tests whether the union of the set of children named Root and the set of children named Jon is non-empty. The expression Root | Jon returns a sequence of nodes, and then that sequence is coerced to a boolean value because if requires a boolean value; if the sequence is non-empty, the effective boolean value is true.
The second conditional tests whether either of the two sets of children (children named Root and children named Jon) is non-empty. The expression Root or Jon returns a boolean value, and since the operator or requires boolean arguments, the two sets are each coerced to boolean, and then the or operator is applied.
The outcome is the same, but (as you can see) the two expressions reach that outcome in subtly different ways.
From Documentation
| - The union operator. For example, the match attribute in the element <xsl:template match="a|b"> matches all <a> and <b> elements
or - Tests whether either the first or second expressions are true. If the first expression is true, the second is not evaluated.
Related
I am trying to optimize my IF statement in Lua. When there are two conditions in an IF statement with the AND operator, does Lua read left to right and stop as soon as it reaches one false? That is, if there is a condition which is quick to check and a condition which is slower to check, is it more efficient to put the condition which is quick to check first (i.e. left most)?
For example, assume I have two functions that return true or false, quick_fn() and slow_fn(), and I want to execute code only if both functions return true. In terms of speed, is there a difference between the following two ways of writing this code? If Option #1 is equivalent, should I always be putting the quick_fn() in the leftmost spot?
Option #1:
if quick_fn() AND slow_fn() then
[code]
end
Option #2:
if quick_fn() then
if slow_fun() then
[code]
end
end
This is explained in the Lua documentation (emphasis added):
The negation operator not always returns false or true. The
conjunction operator and returns its first argument if this value is
false or nil; otherwise, and returns its second argument. The
disjunction operator or returns its first argument if this value is
different from nil and false; otherwise, or returns its second
argument. Both and and or use short-circuit evaluation; that is, the
second operand is evaluated only if necessary.
Note that the operator is spelled and, not AND. Lua is case-sensitive.
I know this has been asked before, but what is the exact difference between the concept of a sequence in XSLT 2 and the earlier node set?
Also in which case/form are duplicates allowed in a sequence? If there are duplicates, would count(node1|node1) = 1 be true?
Expanding Max Toro's answer, there are two main differences between XSLT 1.0 node-sets and XSLT 2.0 sequences:
(1) sequences are ordered
(2) sequences may contain atomic values (such as strings and numbers) as well as nodes. (In 3.0 they may also contain other kinds of item, such as functions, maps, and arrays).
Rather than support both sets and sequences in 2.0, it was decided to only have sequences, but that some operations would cause a sequence of nodes to be sorted into document order with duplicates eliminated. The main operations that do this are:
(a) the union ('|'), intersect, and except operators.
(b) the path operator "/" (in the case where the right-hand operand returns nodes)
Because '|' eliminates duplicates, count($n|$n) returns count($n) (which is 1 if $n is a singleton). However, count(($m, $n)) returns count($m) + count($n), because the "," operator concatenates two sequences without eliminating duplicates. Similarly the new '!' operator does not eliminate duplicates, so count($m!$n) is count($m)*count($n).
Sequences are ordered and may contain duplicates. The path operator (/) eliminates duplicates and returns nodes in document order.
Sequences may contain atomic values.
What does the below code do? How can I write this OCL expression when there is one element instead of elements?
In other words, I don't understand which elements does the code collect?
Since "collect" is used when we have more than one element, if I have one element (instead of elements), what changes occure to "-> collect (s|thisModule.CreateMatchClass(s))" part of that expression?
s.source.elements -> collect (s|thisModule.CreateAnyMatchClass(s))
Your OCL expression simply 'create' elements (regarding the name of the thismodule function) from the elements that are in s.source. The created elements are then returned as a Collection:
s.source.elements return (supposedly) a Collection (could be a Set/Sequence...) by navigating from s
collect(...) gathers the results of its parameter expression
How to change the expression if the relation elements is not 0..* anymore but 0..1 or 1..1?
Indeed, collect(...) works with collections, but -> is also an implicit converter to a Set. The page 15 of the OCL specification states:
The "->" navigation shorthand performs an implicit set conversion of an object.
anObject->union(aSet) is a shorthand for anObject.oclAsSet()->union(aSet)
It means that in the case element (I removed the final 's') is a "single" relationship and s.source.element returns a single element, the call s.source.element->... is equivalent to s.source.element.oclAsSet()->.... In your case, whether elements is many or not, the expression is still the same:
s.source.elements -> collect (s|thisModule.CreateAnyMatchClass(s))
This expression will work in both cases.
If you really don't want the collect and if you have your elements relationship which is single, you can write this also:
thisModule.createAnyMatchClass(s.source.elements)
For an assignment, I have to create a type inference relation. here's the approach I used
tuples([]).
tuples(_|_).
type(tuples([]),tuples([])).
type(tuples(X|T),tuples(Y|Z)) :- type(tuples(T),tuples(Z)),type(X,Y).
I have already defined the type relation for all possible terms required for my assignment where y is the type of X in type(X,Y). For defining types of n-tuples, I used the approach similiar to the one used for appending lists.
But prolog always returns false when I ask
?-type(tuples([3,str]),Z)
or even
?-type(tuples([3,str]),tuples(Z))
or
?-type(tuples([3,str,4,abc,5,6]),Z)
i.e a list of length n, the answer returned is false.
Nothing changed even when I revered the sub-rules in the last rule.
tuples([]).
tuples(_|_).
type(tuples([]),tuples([])).
type(tuples(X|T),tuples(Y|Z)) :- type(X,Y),type(tuples(T),tuples(Z)).
I am not asking for alternative approaches to type of tuples to help me in my assignment but I can't figure out why this approach is not working.
It looks like your definition of a tuple is a List with length 2.
This rule does not check for that:
tuples(_|_).
What you probably want is this:
tuples([_,_]).
If you want it to check for any length list, use:
tuples([_|_]).
In the latter rule, the first wildcard represents the first item in the list (the head) and the second wildcard represents the rest of the list (the tail).
I'm trying to match all a/c elements that have a b sibling. I've tried:
<xsl:template match="a/b/../c">
but I get "Cannot convert the expression {..} to a pattern" from Saxon.
My XSLT/XPath skills are basic at best...
<xsl:template match="a[b]/c">
Explanation: match any c element that is a child of an a element that has a b child.
You should also be able to use .. in a predicate:
<xsl:template match="a/c[../b]">
which is similar to what you were trying.
The reason you can't use .. directly in a match pattern (i.e. outside of a predicate) is that patterns are not XPath expressions, even though they look and behave very similarly. In particular, only "downward" axes (child::, descendant::, and attribute::) are allowed directly in patterns. (The only explicit axes allowed by the spec are child:: and attribute::. descendant:: is implicitly allowed via the // between pattern steps. Saxon seems to bend the rules a bit here, allowing an explicit descendant:: axis, and even descendant-or-self::!)
The reason given for the restriction on axes is that (a) other axes are rarely needed in patterns, and (b) this allows XSLT processors to be much more efficient in testing for matches.
But predicates in patterns are defined with the same syntax rules as in XPath expressions (with some restrictions in XSLT 1.0, like not allowing variable references or current()). So you can use other axes, like parent::, or the abbreviation ...
This XPath expression seems to do the job (may be not optimal):
//a|//c[following-sibling::b or preceding-sibling::b]
Edit:
In case LarsH is right, it should be //a/c instead of //a|//c.