This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 27455 - [xp31[ Unary lookup: specification gaps
Summary: [xp31[ Unary lookup: specification gaps
Status: RESOLVED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XPath 3.1 (show other bugs)
Version: Last Call drafts
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Jonathan Robie
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-27 11:16 UTC by Michael Kay
Modified: 2014-12-15 01:13 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2014-11-27 11:16:46 UTC
@@ comments on the text flagged with "@@"

[76]   	UnaryLookup	   ::=   	"?" KeySpecifier
[53]   	KeySpecifier	   ::=   	NCName | IntegerLiteral | ParenthesizedExpr | "*"
UnaryLookup returns a sequence of values selected from the context item, which must be a map or array. If the context item is not a map or an array, an error is raised [err:XPTY0tbd].

@@ already raised: tbd needs to be defined.

If the KeySpecifier is not a wildcard

@@ nowhere is it said that "wildcard" means "*"

, the semantics of the UnaryLookup operator are as follows: Let KS denote the items in the sequence to which the KeySpecifier evaluates. The UnaryLookup operator is equivalent to the following expression:

for $k in KS
return .($k)

@@ This equivalence does not hold in the error case where teh context item is a function other than a map or array.

Unary lookup is used primarily in predicates (e.g. $map[?name='Mike'] or with the simple mapping operator (e.g. $maps ! ?name='Mike'). 

@@ In XSLT, which makes much more use of the context item, it is likely to be used much more widely, e.g <xsl:sort select="?id"/>.

See 3.11.3.2 Postfix Lookup for the postfix lookup operator.

Examples:

?name is equivalent to .("name"), an appropriate lookup for a map.
?2 is equivalent to .(2), an appropriate lookup for an array or an integer-valued map.
?($a) is equivalent to for $k in $a return .($k), allowing keys for an array or map to be passed using a variable.
?(2 to 4) is equivalent to for $k in (2,3,4) return .($k), a convenient way to return a range of values from an array.

@@ It might be worth pointing out that the function signature for array functions expects xs:integer, the supplied value is atomized, and converted to integer if it is untyped atomic. But supplying a double will give a type error. So if @id is untypedAtomic "3", then ?(@id) works, but ?(@id+1) does not.

@@ It might also be worth a reminder that you get a dynamic error if the subscript is out of bounds. For example

([1,2,3], [1,2,5], [1,2])[?3 = 5] gives an error because ?3 on one of the items in the sequence fails. However, exists(([1,2,3], [1,2,5], [1,2])[?3 = 5]) might succeed because of early exit.

If the KeySpecifier is "*" and the context item is a map, unary lookup is equivalent to the following expression:

for $k in map:keys(.)
return .($k)

@@ We don't provide an equivalence for the case where the KeySpecifier is "*" and the context item is an array. I think the equivalence is

for $k in 1 to array:size(.)
return .($k)
Comment 1 Liam R E Quin 2014-12-10 01:07:09 UTC
I think all of this is editorial execpt choosing which error gets raised;
is that right?
Comment 2 Jonathan Robie 2014-12-15 01:13:37 UTC
(In reply to Michael Kay from comment #0)

> @@ already raised: tbd needs to be defined.


Done.
 
> If the KeySpecifier is not a wildcard
> 
> @@ nowhere is it said that "wildcard" means "*"
> 
> , the semantics of the UnaryLookup operator are as follows: Let KS denote
> the items in the sequence to which the KeySpecifier evaluates. The
> UnaryLookup operator is equivalent to the following expression:
> 
> for $k in KS
> return .($k)
> 
> @@ This equivalence does not hold in the error case where teh context item
> is a function other than a map or array.

The sentence before this says it's an error if the context item is not a map or array:

<quote>
UnaryLookup returns a sequence of values selected from the context item, which must be a map or array. If the context item is not a map or an array, a dynamic type error is raised [err:XPTY0004].
</quote>

> Unary lookup is used primarily in predicates (e.g. $map[?name='Mike'] or
> with the simple mapping operator (e.g. $maps ! ?name='Mike'). 
> 
> @@ In XSLT, which makes much more use of the context item, it is likely to
> be used much more widely, e.g <xsl:sort select="?id"/>.

I deleted the word "primarily.
 
> See 3.11.3.2 Postfix Lookup for the postfix lookup operator.
> 
> Examples:
> 
> ?name is equivalent to .("name"), an appropriate lookup for a map.
> ?2 is equivalent to .(2), an appropriate lookup for an array or an
> integer-valued map.
> ?($a) is equivalent to for $k in $a return .($k), allowing keys for an array
> or map to be passed using a variable.
> ?(2 to 4) is equivalent to for $k in (2,3,4) return .($k), a convenient way
> to return a range of values from an array.
> 
> @@ It might be worth pointing out that the function signature for array
> functions expects xs:integer, the supplied value is atomized, and converted
> to integer if it is untyped atomic. But supplying a double will give a type
> error. So if @id is untypedAtomic "3", then ?(@id) works, but ?(@id+1) does
> not.

OK.  I added these examples.

> @@ It might also be worth a reminder that you get a dynamic error if the
> subscript is out of bounds. For example
> 
> ([1,2,3], [1,2,5], [1,2])[?3 = 5] gives an error because ?3 on one of the
> items in the sequence fails. However, exists(([1,2,3], [1,2,5], [1,2])[?3 =
> 5]) might succeed because of early exit.

I added the first part of this but not the second.

> @@ We don't provide an equivalence for the case where the KeySpecifier is
> "*" and the context item is an array. I think the equivalence is
> 
> for $k in 1 to array:size(.)
> return .($k)

Ouch! Back when arrays were maps, the old equivalence worked, but this did need fixing. Done now.