- From: Robie, Jonathan <jonathan.robie@emc.com>
- Date: Thu, 10 Sep 2015 16:12:38 +0000
- To: Michael Kay <mike@saxonica.com>
- CC: Public Joint XSLT XQuery XPath <public-xsl-query@w3.org>
Before responding further, let me copy Liam's proposal from the original member list to the current public list in case others are listening in. Mike is responding to this proposal, which was prepared by Liam. Jonathan This is revised to take Mike Kay's comments into account and to be more formal. I've omitted justification and use cases, but will note this syntax also means we don't have to try and incorporate literal JSON syntax into the XQuery grammar directly, because we can meet all of our use cases/needs using foreign blocks and a parse-json() function. An implementation can obviously optimize a call to parse-json() with a string literal. I didn't use Mike Kay's suggested name "computed string constructor" because currently those all use curly braces in exactly the way we need to avoid in order to support JSON :-) so I went for Extended string constructor and (as Mike suggested) Literal string constructor. It might go in or after 3.16.5 Constructor Functions, e.g. 3.16.5.1 Extended String Constructors An <term>Extended String Constructor</term> is an alternate syntax for string construction in which the result of evaluating embedded expressions can be included. The syntax is suitable for containing fragments of JavaScript, JSON, CSS, SPARQL or other languages that might use curly braces, double and single quotes, or be difficult or tedious to construct directly in XQuery using other mechanisms. [201] ExtStringConstructor ::= "~~$" . ExtStringText "$~~" [203] ExtStringText := ((Char* - "${") | "${" Expr "}")* An extended string constructor allows embedded expressions, marked as ${ Expr }. Conceptually, they are processed by the following steps: 1. Each consecutive sequence of literal characters in the attribute content is processed as a string literal containing those characters. Note: & is not recognized as special; $ is only recognized when immediately followed by "{". Line endings are processed as elsewhere in XQuery; no other processing is performed on literal characters. 2. Each enclosed expression within ${ up to the matching } is evaluated as for enclosed expressions in attribute constructors: <!--* copied from 3.9.1.1 *--> a. Atomization is applied to the value of the enclosed expression, converting it to a sequence of atomic values. b. If the result of atomization is an empty sequence, the result is the zero-length string. Otherwise, each atomic value in the atomized sequence is cast into a string. c. The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. <!--* end of copied text *--> 3. Adjacent strings resulting from the above steps are concatenated with no intervening blanks. Note: a foreign block could be included within such an expression, and its end delimiter would not end the outer foreign block. A <term>literal string constructor</term> is similar to the extended string constructor but does not support enclosed expressions: it can contain any sequence of characters allowed in an XQuery document, and no special characters are recognized inside it. The result has type xs:string. [202] LiteralStringConstructor := "~~!" (Char* - "!~~") "!~~" Line endings within a literal string constructor are normalized as elsewhere in XQuery. Examples: The following example from json.org adds a session ID member that is generated dynamically: declare variable $json := ~~$ {"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}, {"callback": null }, {"session-id": ${ get-session-id() } } ] } }} $~~ ; The foreign text blocks can be used anywhere a string or string-valued expression can be used: string-join( for $i in ("hello", ~!world!~~) return $i, " " ) The construct can be nested: string-length(~~$There were ${ count($e/attendee) } daleks in attendance at the party, and ${ concat($e/attendee[1]/name, ~~$-dalek$~~) } won the Exterminate-My-Leader competition.$~~) [end of proposal] Liam
Received on Thursday, 10 September 2015 16:13:28 UTC