comma operator in xpath, is it like c?

2019-07-24 20:07发布

问题:

    <xsl:variable name="html-output-name" 
         select="(if(@index and @index eq 'true') 
             then concat($default-name, '.html') 
             else (), 
         @html-output-name,
         @output-name, 
         $default-html)[1]" />

I see what the 'if' is doing, but I'm not sure how to make sense of the rest of the items in the command, and then the [1] at the end. Does this add up to 'the first non-empty item in the list?"

回答1:

From http://www.w3.org/TR/xpath20/#construct_seq

Definition: One way to construct a sequence is by using the comma operator, which evaluates each of its operands and concatenates the resulting sequences, in order, into a single result sequence

Partial BNF:

[2] Expr ::=ExprSingle(","ExprSingle)*

And from http://www.w3.org/TR/xpath20/#id-filter-expr

[Definition: A filter expression consists simply of a primary expression followed by zero or more predicates. The result of the filter expression consists of the items returned by the primary expression, filtered by applying each predicate in turn, working from left to right.] If no predicates are specified, the result is simply the result of the primary expression. The ordering of the items returned by a filter expression is the same as their order in the result of the primary expression. Context positions are assigned to items based on their ordinal position in the result sequence. The first context position is 1.

Question:

Does this add up to 'the first non-empty item in the list?

Answer: Not quite. This selects the first item in the list. There are no empty item, but empty sequence. And because there aren't nested sequence (formaly tuples), they are just concatenated as a flat sequence.



回答2:

The idiom (A, B, C)[1] in XPath 2.0 is often used to mean "if A exists, then A; otherwise if B exists, then B; otherwise if C exists then C; otherwise nothing." Which I guess matches your paraphrase "the first non-empty item in the list". Technically it builds a sequence containing all the items selected by A, then all the items selected by B, then all the items selected by C, and then it selects the first item in the list. But because of lazy evaluation and pipelining, it's unlikely it will actually build the whole list.