Proposals for XPath and XQuery Syntax Extensions

31 views
Skip to first unread message

Reece Dunn

unread,
Oct 14, 2018, 10:55:20 AM10/14/18
to EXPath
Hi all,

I have been implementing an XQuery plugin for the IntelliJ IDE (https://github.com/rhdunn/xquery-intellij-plugin) and in doing so have found the need for various XQuery syntax extensions when describing built-in functions from different vendors. I have been documenting the extensions from various vendors and my plugin in https://github.com/rhdunn/xquery-intellij-plugin/blob/master/docs/XQuery%20IntelliJ%20Plugin.md.

The extensions I am using, and considering using, in my plugin are as follows:

Unions and Tuples

    ItemType ::= ... | ParenthesizedSequenceType
    ParenthesizedSequenceType ::= ParenthesizedItemType | ItemTypeUnion | TupleSequenceType
    ItemTypeUnion ::= "(" ItemType ("|" ItemType)* ")"
    TupleSequenceType ::= "(" ItemType ("," ItemType)* ")"

NOTE: ParenthesizedSequenceType replaces ParenthesizedItemType in the ItemType EBNF symbol.

I am using TupleSequenceType for the definition of the MarkLogic math:modf function, which returns a (xs:double, xs:integer)sequence.

I am using ItemTypeUnion for various functions that take arguments with multiple possible values, or return one of a set of types. For example:

    declare function load-json($filename as xs:string) as (map(*) | array(*)) external;
    declare function crypto:hmac(
        $message as xs:string,
        $key as (xs:string | xs:hexBinary | xs:base64Binary),
        $algorithm as xs:string
    ) as xs:base64Binary external;


I have parser support for these that I am using for my plugin.

Tuple Decomposition

I have not provided an implementation of this in my plugin, but is something that is supported in languages like Python and C# that support tuple types. For example:

    let $c as complex := (xs:double("1"), xs:double("2"));
    let ($re, $im) := $c; (: error if there are not 2 items in the sequence :)

    let ($heading as array(xs:string), $rows as array(xs:string)*) := load-csv("test.csv");

It may be useful to support a more consice syntax for specifying the cardinality of the last variable, such as:

    let ($heading, $rows*) := load-csv("test.csv");

Annotated Sequence Types

    ItemType ::= ... | AnnotatedFunctionOrSequence
    AnnotatedFunctionOrSequence ::= AnnotatedSequenceType | FunctionTest
    AnnotatedSequenceType ::= Annotation Annotation* "for" SequenceType


NOTE: AnnotatedFunctionOrSequence replaces FunctionTest in the ItemType EBNF symbol.

I have has the need to provide annotations on types (used to provide versioning information on types). For example:

    declare type hmac-key = (
      %a:since("expath-crypto", "20110810") %a:until("basex", "8.6") for xs:string |
      %a:since("basex", "8.6") for xs:anyAtomicType
    );


This is also using the Saxon 9.8 type declaration vendor extension.

I have parser support for this that I am using for my plugin.

Annotation Declarations

    AnnotatedDecl ::= "declare" Annotation* (VarDecl | FunctionDecl | AnnotationDecl)
    AnnotationDecl ::= "annotation" EQName ArgumentList? ("for" AnnotationScopeList)?
    AnnotationScopeList ::= AnnotationScope ("," AnnotationScope)*
    AnnotationScope ::= "function" | "variable" | "type" | "annotation"


For example:

    declare annotation private for function, variable;
    declare %compatibility-syntax annotation updating for function;
    declare annotation a:since($vendor as xs:string, $version as xs:string) for function, variable;


I haven't yet implemented this syntax extension in my plugin, but intend to. I am currently specifying the format of annotations as functions, for example:

    declare %a:annotation function a:annotation() external;
    declare %a:annotation function a:deprecated($vendor-or-spec as xs:string, $version as xs:string) external;


but having these as a separate syntax type would make it easier to avoid calling them in XQuery code and to look them up when locating annotations in an XQuery processor.

The following would be functionally identical:

    declare annotation private for function, variable;
    declare annotation private() for function, variable;

Variadic Function Arguments

The fn:concat function is declared as being variadic. The XPath and XQuery Functions and Operators 3.1 specification notes that this is the only function in that document that supports variadic arguments. Various vendors have vendor specific built-in functions that allow variadic arguments. I am currently using an annotation to specify a function as being variadic:

    declare %a:since("xpath-functions", "1.0-20070123") %a:variadic("xs:anyAtomicType?") function fn:concat(
        $arg1 as xs:anyAtomicType?,
        $arg2 as xs:anyAtomicType?
    ) as xs:string external;


I am considering using a syntax extension for this instead. For example:

    declare %a:since("xpath-functions", "1.0-20070123") function fn:concat(
        $arg1 as xs:anyAtomicType?,
        $args as variadic array(xs:anyAtomicType?)
    ) as xs:string external;


The behaviour of this would be to convert the remaining arguments to an array of the specified type (an ArrayTest), and pass that array as the parameter. The specific syntax could be something like:

    ParamList ::= Param ("," Param)* ("," VariadicParam)?
    Param ::= "$" EQName TypeDeclaration?
    VariadicParam ::= "$" EQName "as" "variadic" ArrayTest


Kind regards,
Reece

Adam Retter

unread,
Oct 14, 2018, 1:11:47 PM10/14/18
to exp...@googlegroups.com
Hi Reece,

Interesting stuff. I can see some use for some of these myself. In
terms of syntax extensions, ideally we would want to get those into an
XPath spec at the W3C, that Working Group is on hiatus at the moment.
However, if we could argue the case that there is enough stuff and
enough interest, it may be possible to get something up and going,
preferably with the aim of standardising a few known things quickly.

Personally there are some other things I would also like to see, I
have been calling these my "XQuery 3.2 Wishlist":

** Default values for parameters in function signatures
1. When specifying a function, e.g declare function local:my-fn($x,
$y := "default", $z := map{ "a" : "Monday", "b" : "Tuesday" })
2. When calling a function, default values may be omitted.

** Named parameters when passing arguments to functions, this can help
with code readability
1. e.g. when calling function, e.g. local:my-fn($x := "xx", $y := "other")

** Ternary operator
1. e.g. $a eq $b ? "hello" : "goodbye"

** Record Type
1. Similar to map in someways but fixed length and statically checked names
2. Basically allows you to create a union record of types
3. e.g. declare variable $v as record { $a as xs:string := "hello",
$b := <b/> }

I guess in some ways the Record Type is similar to your tuple and union types.

I wonder if we should find somewhere to collect all of these ideas
together? Perhaps a project under the EXPath repo is enough, where we
collate proposals with attribution. Perhaps if we get enough stuff
together we could do something...

Cheers Adam.
> --
> You received this message because you are subscribed to the Google Groups "EXPath" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to expath+un...@googlegroups.com.
> To post to this group, send email to exp...@googlegroups.com.
> Visit this group at https://groups.google.com/group/expath.
> For more options, visit https://groups.google.com/d/optout.



--
Adam Retter

skype: adam.retter
tweet: adamretter
http://www.adamretter.org.uk

Loren Cahlander

unread,
Oct 14, 2018, 1:19:10 PM10/14/18
to EXPath, Loren Cahlander
The xqDoc parser also takes into account MarkLogic’s new node constructors to generate JSON:


New Node Constructor

MarkLogic 8 extends the XQuery/XPath data model to include new node constructors to support JSON data types. JSON strings are text() nodes, just like in XML.

• object-node { }
• array-node { }
• null-node {}
• number-node {}
• boolean-node {}
Here is an example on how to construct a JSON object node with those constructors:

object-node { "p1" : "v1", "p2" : array-node {1,2,3} , "p3" : fn:true(), "p4" : null-node {} } =>
{ "p1" : "v1", "p2" : [1, 2, 3] , "p3" : true, "p4" : null }
signature.asc

Reece Dunn

unread,
Oct 14, 2018, 1:59:40 PM10/14/18
to EXPath
On Sunday, 14 October 2018 18:11:47 UTC+1, Adam Retter wrote:
Hi Reece,

Interesting stuff. I can see some use for some of these myself. In
terms of syntax extensions, ideally we would want to get those into an
XPath spec at the W3C, that Working Group is on hiatus at the moment.
However, if we could argue the case that there is enough stuff and
enough interest, it may be possible to get something up and going,
preferably with the aim of standardising a few known things quickly.

That would be great.
 
Personally there are some other things I would also like to see, I
have been calling these my "XQuery 3.2 Wishlist":

** Default values for parameters in function signatures
  1. When specifying a function, e.g declare function local:my-fn($x,
$y := "default", $z := map{ "a" : "Monday", "b" : "Tuesday" })
  2. When calling a function, default values may be omitted.

** Named parameters when passing arguments to functions, this can help
with code readability
  1. e.g. when calling function, e.g. local:my-fn($x := "xx", $y := "other")

** Ternary operator
  1. e.g. $a eq $b ? "hello" : "goodbye"

** Record Type
  1. Similar to map in someways but fixed length and statically checked names
  2. Basically allows you to create a union record of types
  3. e.g. declare variable $v as record { $a as xs:string := "hello",
$b := <b/> }

 I guess in some ways the Record Type is similar to your tuple and union types.

The Saxon XQuery processor also has a named tuple type test http://www.saxonica.com/documentation/index.html#!extensions/syntax-extensions/tuple-types that is similar to your record type proposal.
 
I wonder if we should find somewhere to collect all of these ideas
together? Perhaps a project under the EXPath repo is enough, where we
collate proposals with attribution. Perhaps if we get enough stuff
together we could do something...

That would be great. As I mentioned, I have been documenting them in a W3C specification like file in my XQuery plugin repository, but am willing to contribute the content of that to EXPath/W3C as necessary.

I'm also willing to add support for these extensions in the lexer/parser of my plugin as needed.

Kind regards,
Reece

Michael Kay

unread,
Oct 14, 2018, 2:53:42 PM10/14/18
to exp...@googlegroups.com


> On 14 Oct 2018, at 18:11, 'Adam Retter' via EXPath <exp...@googlegroups.com> wrote:
>
> Hi Reece,
>
> Interesting stuff. I can see some use for some of these myself. In
> terms of syntax extensions, ideally we would want to get those into an
> XPath spec at the W3C, that Working Group is on hiatus at the moment.
> However, if we could argue the case that there is enough stuff and
> enough interest, it may be possible to get something up and going,
> preferably with the aim of standardising a few known things quickly.

In the absence of a W3C group for defining XP/XQ 3.1, I think this could be the useful focus of an EXPath activity. Otherwise there's a great danger of vendors diverging and producing different extensions, sometimes overlapping.
>
> Personally there are some other things I would also like to see, I
> have been calling these my "XQuery 3.2 Wishlist":
>
> ** Default values for parameters in function signatures
> 1. When specifying a function, e.g declare function local:my-fn($x,
> $y := "default", $z := map{ "a" : "Monday", "b" : "Tuesday" })
> 2. When calling a function, default values may be omitted.

The problem here is that you're effectively defining another function with different arity. That's not a stopper, but it requires careful definition of the semantics.
>
> ** Named parameters when passing arguments to functions, this can help
> with code readability
> 1. e.g. when calling function, e.g. local:my-fn($x := "xx", $y := "other")

That's potentially a biggie. Perhaps it's OK if we just define it as syntactic sugar for calling a function whose last argument is a map

f(a :="x", b :="y") ==> f(map{'a':'x', 'b':'y'})
>
> ** Ternary operator
> 1. e.g. $a eq $b ? "hello" : "goodbye"

I don't think this is compatible with our current use of "?" as lookup operator. I agree it would be nice to have something more concise than the current if-then-else but it might be hard to find something acceptable.
>
> ** Record Type
> 1. Similar to map in someways but fixed length and statically checked names

That's basically the tuple type I've defined in Saxon.

> 2. Basically allows you to create a union record of types
> 3. e.g. declare variable $v as record { $a as xs:string := "hello",
> $b := <b/> }
>
> I guess in some ways the Record Type is similar to your tuple and union types.
>
> I wonder if we should find somewhere to collect all of these ideas
> together? Perhaps a project under the EXPath repo is enough, where we
> collate proposals with attribution. Perhaps if we get enough stuff
> together we could do something...
>

Yes, I think we could.

Michael Kay
Saxonica

Dimitre Novatchev

unread,
Oct 14, 2018, 3:29:24 PM10/14/18
to exp...@googlegroups.com
Hi everyone,

In the past I proposed an import declaration in XPath -- that would read from an URL (most probably file) a set of variable definitions that are predefined at that location.

The main purpose of this is to import sets of XPath 3 function definitions, so that users can use and create their own "libraries" of useful functions and not have to write them thousands of times over and over again. This achieves code brevity/conciseness and abstraction (hiding). Code sharing is another obvious achievement.

So, something like:

import from {url} into {namespace}

Then use in your code:

{namespace}:someImportantFunction()

Of course, I will implement this in my own public repository, but isn't it the goal of EXPath to collect such useful functionality in the same place and avoid the problems of redundancy?

Cheers,
Dimitre

Christian Grün

unread,
Oct 14, 2018, 5:21:34 PM10/14/18
to EXPath
Hi Reece,

Thanks for the link to your XQuery plugin. The list of vendor-specific
extensions is quite instructive.

And thanks triggering the ongoing discussion. Obviously, it’s an easy
task to ask for new features, and a much more tedious task to get them
standardized. I remember there was a similar "xquery 3.1 wishlist"
discussion on the list in 2015:

http://x-query.com/pipermail/talk/2015-June/thread.html#4934

But we’ll be glad to contribute to the standardization of new
XPath/XQuery features we can all agree upon; and it’s nice to see that
we may have at least 3 implementations supporting this initiative.

Some feedback on the extensions that seem most relevant to us:

> Tuple Decomposition

+1 for this one. It was also requested by some of our users in the past.

> ** Default values for parameters in function signatures

Our experience was that such an enhancement requires some careful
thoughts (Michael uttered similar concerns); but we’d be glad to see
such a feature part of XQuery 3.2 (or 3.1 EX).

> ** Ternary operator
> 1. e.g. $a eq $b ? "hello" : "goodbye"

I remember that Adam and me requested support for this operator
multiple times in the past. Some semantics have been assigned to the
question mark now, but maybe we can find a syntax that’s not too
idiosyncratic, and that is used by other languages as well. The ??/!!
syntax from perl could be a possible candidate (see
https://en.wikipedia.org/wiki/%3F).

And I would love to have a null coalescing (this-or-default) operator
in XQuery. It is readily available in many other languages:

https://en.m.wikipedia.org/wiki/Null_coalescing_operator

In BaseX, we just added a convenience function to fill the gap:

http://docs.basex.org/wiki/Utility_Module#util:or

Many code snippets could be much shorter if we could get rid of
constructs like "if (X) then X else Y", or "(X, Y)[1])" or
"head((X,Y))" (which only work if X and Y are single items). A
possible operator could be "?:"; an alternative, which would go hand
in hand with the ternary operator syntax of Perl would be "?!".

A related suggestion: The 'else' branch of the 'if' expression could
be made optional (if omitted, the empty sequence could be returned).
The required modifications in the XQuery grammar would be minimal.

if(A) then B ≙ if(A) then B else ()

And I’m adding a request for another convenience operator that was
proposed for 3.1:

https://www.w3.org/Bugs/Public/show_bug.cgi?id=29393

The "==>" syntax was proposed to apply the function of the right-hand
operand to each item of the left-hand operand:

("a", "b", "c") ! (. => upper-case())
("a", "b", "c") ==> upper-case()

An alternative syntax (which combined "!" and "=>") could be "!>".

Many ideas, and a lot of work to get this specified. We could continue
to discuss the new feature requests in the EXPath/EXQuery Github
repositories or in the Wiki of the W3 EXPath Community Group; what do
you think?

https://www.w3.org/community/expath/wiki/Main_Page
https://github.com/expath/expath-cg
https://github.com/exquery/exquery

Best,
Christian

Adam Retter

unread,
Oct 15, 2018, 2:37:06 AM10/15/18
to exp...@googlegroups.com
> > ** Default values for parameters in function signatures
> > 1. When specifying a function, e.g declare function local:my-fn($x,
> > $y := "default", $z := map{ "a" : "Monday", "b" : "Tuesday" })
> > 2. When calling a function, default values may be omitted.
>
> The problem here is that you're effectively defining another function with different arity. That's not a stopper, but it requires careful definition of the semantics.
> >

That's one approach. From an implementation perspective, I can see
other approaches where these default arguments do not cause functions
of different arities to be generated/made available. Instead
substitution could be done as query macros, or query optimization
stage, or even some further information could be attached to the
full-arity function signature, so when resolving the known functions
in the static context we can make decisions.

We would certainly need to define what happens when you have two
function definitions like, local:func1($a), local:func1($a, $b :=
"default-value"). Not necessarily the approach we have to take, but
the approach in C++ is to allow the definition, but to report that any
call to a function named func1 with a single parameter is ambiguous,
e.g.

void func1(int a);
void func1(int a, int b = 2);

int main(int argc, char* argv[]) {
func1(123);
}

$ gcc test.cc
test.cc:5:3: error: call to 'func1' is ambiguous
func1(123);
^~~~~
test.cc:1:6: note: candidate function
void func1(int a);
^
test.cc:2:6: note: candidate function
void func1(int a, int b = 2);
^
1 error generated.


> > ** Named parameters when passing arguments to functions, this can help
> > with code readability
> > 1. e.g. when calling function, e.g. local:my-fn($x := "xx", $y := "other")
>
> That's potentially a biggie. Perhaps it's OK if we just define it as syntactic sugar for calling a function whose last argument is a map

Can you explain the potential complexity that you see here? My
intention was not to have the defined function need to use any
particular type of argument. I just saw it as syntactic sugar that
could be erased once it had been statically checked. I imagined the
query pre-processor would reorder the arguments correctly so that
given the function:

declare function local:func($a as xs:string, $b as xs:string, $c as
xs:int) { ($a, $b, $c) }

either of the following would be valid and produce ("hello", "there", 12):

local:func1($a := "hello", $b := "there", $c := 12)
local:func1($a = "hello", $c := 12, $b := "there")
local:func1(hello, "there", $c := 12)
local:func1($a := hello, "there", $c := 12)

However this would not be valid because the second parameter is specified twice:

local:func1($a = "hello", 12, $b := "there")


> f(a :="x", b :="y") ==> f(map{'a':'x', 'b':'y'})
> >
> > ** Ternary operator
> > 1. e.g. $a eq $b ? "hello" : "goodbye"
>
> I don't think this is compatible with our current use of "?" as lookup operator. I agree it would be nice to have something more concise than the current if-then-else but it might be hard to find something acceptable.
> >

Ah yes. Unfortunately that "?" has already been taken, well some other
symbol (or combination of) would suit me too... perhaps just "??" is
simple enough?

Michael Kay

unread,
Oct 15, 2018, 3:48:02 AM10/15/18
to exp...@googlegroups.com


> On 15 Oct 2018, at 07:36, 'Adam Retter' via EXPath <exp...@googlegroups.com> wrote:
>
>>> ** Default values for parameters in function signatures
>>> 1. When specifying a function, e.g declare function local:my-fn($x,
>>> $y := "default", $z := map{ "a" : "Monday", "b" : "Tuesday" })
>>> 2. When calling a function, default values may be omitted.
>>
>> The problem here is that you're effectively defining another function with different arity. That's not a stopper, but it requires careful definition of the semantics.
>>>
>
> That's one approach. From an implementation perspective, I can see
> other approaches where these default arguments do not cause functions
> of different arities to be generated/made available. Instead
> substitution could be done as query macros, or query optimization
> stage, or even some further information could be attached to the
> full-arity function signature, so when resolving the known functions
> in the static context we can make decisions.

The rules have to handle dynamic function calls as well as static calls. From this perspective the principle that a function is uniquely identified by name+arity is fundamental. I've no problem with the principle that when the last argument has a default, the function declaration is effectively declaring two functions with different arity. But it gets complicated if more than one argument can be defaulted.
>
>
>>> ** Named parameters when passing arguments to functions, this can help
>>> with code readability
>>> 1. e.g. when calling function, e.g. local:my-fn($x := "xx", $y := "other")
>>
>> That's potentially a biggie. Perhaps it's OK if we just define it as syntactic sugar for calling a function whose last argument is a map
>
> Can you explain the potential complexity that you see here? My
> intention was not to have the defined function need to use any
> particular type of argument. I just saw it as syntactic sugar that
> could be erased once it had been statically checked. I imagined the
> query pre-processor would reorder the arguments correctly so that
> given the function:
>
> declare function local:func($a as xs:string, $b as xs:string, $c as
> xs:int) { ($a, $b, $c) }
>
> either of the following would be valid and produce ("hello", "there", 12):

> local:func1($a := "hello", $b := "there", $c := 12)
> local:func1($a = "hello", $c := 12, $b := "there")
> local:func1(hello, "there", $c := 12)
> local:func1($a := hello, "there", $c := 12)

You're assuming that the argument names are present in the signature. Currently for the very rigid binding of static function calls in XQuery, that's OK. It doesn't work for dynamic calls in XQuery, and it doesn't work for static calls in XSLT when you have function overriding either using xsl:import or xsl:use-package - there's no requirement for an overriding function to use the same argument names as the function it overrides.


I think in any case the syntax is more useful when there's a wide choice of possible arguments and most of them have defaults. The problem of arity being part of the function's identity means, i think, that this is best modelled as treating all the optional arguments as being bundled into one formal map-valued argument.

>
> Ah yes. Unfortunately that "?" has already been taken, well some other
> symbol (or combination of) would suit me too... perhaps just "??" is
> simple enough?
>

Yes, I think the Perl syntax A ?? B !! C would work syntactically. Whether it's a big enough win to justify its existence is moot.

The Elvis operator A ?: B meaning "if (exists(A)) then A else B" would also work syntactically.

Michael Kay
Saxonica

Adam Retter

unread,
Oct 15, 2018, 4:38:04 AM10/15/18
to exp...@googlegroups.com
> I remember there was a similar "xquery 3.1 wishlist"
> discussion on the list in 2015:
>
> http://x-query.com/pipermail/talk/2015-June/thread.html#4934

Wow! Your memory is much better than mine Christian :-)


> > ** Ternary operator
> > 1. e.g. $a eq $b ? "hello" : "goodbye"
>
> I remember that Adam and me requested support for this operator
> multiple times in the past. Some semantics have been assigned to the
> question mark now, but maybe we can find a syntax that’s not too
> idiosyncratic, and that is used by other languages as well. The ??/!!
> syntax from perl could be a possible candidate (see
> https://en.wikipedia.org/wiki/%3F).

"??" would suit me just fine.


> And I would love to have a null coalescing (this-or-default) operator
> in XQuery. It is readily available in many other languages:
>
> https://en.m.wikipedia.org/wiki/Null_coalescing_operator
>
> In BaseX, we just added a convenience function to fill the gap:
>
> http://docs.basex.org/wiki/Utility_Module#util:or

Nice. I am used to constructs like this in Scala, e.g.

- Option[T]#orElse
- List[T]#headOption#orElse
- Either#getOrElse
- \/#leftMap

> Many code snippets could be much shorter if we could get rid of
> constructs like "if (X) then X else Y", or "(X, Y)[1])" or
> "head((X,Y))" (which only work if X and Y are single items). A
> possible operator could be "?:"; an alternative, which would go hand
> in hand with the ternary operator syntax of Perl would be "?!".

Or from my crazy mind... we need two versions:

1) if the thing on the left is non-empty then do X:

$result := $left ?> local:right($left)

This is different to "!" as it takes the entire non-empty sequence
from left to right.
In simple terms: "?>" could be read as - "if there is a value on the
left , follow the >"

2) if the thing on the right is empty then do Y:

$result := $left !> local:right($left)

In simple terms "!>" could be read as 0 "if there is not a value on
the left, follow the >"

Arguably I should have just written my function local:right to accept
an empty sequence and return an empty sequence, but hey, sometimes you
have to call other peoples library functions ;-)

Syntax! Meh!

> A related suggestion: The 'else' branch of the 'if' expression could
> be made optional (if omitted, the empty sequence could be returned).
> The required modifications in the XQuery grammar would be minimal.
>
> if(A) then B ≙ if(A) then B else ()

Interesting idea. I wonder if that might cause confusion with existing
code, especially that code that is not well formatted. Another
suggestion (although not better or worse) is to instead add "ifne",
read as "if non empty":

ifne(A) then B ≙ if(A) then B else ()

I guess really this is very similar to the "null coalescing" stuff above.


> And I’m adding a request for another convenience operator that was
> proposed for 3.1:
>
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=29393
>
> The "==>" syntax was proposed to apply the function of the right-hand
> operand to each item of the left-hand operand:
>
> ("a", "b", "c") ! (. => upper-case())
> ("a", "b", "c") ==> upper-case()
>
> An alternative syntax (which combined "!" and "=>") could be "!>".

Erm... I think I am missing some subtly here, but isn't this just:

("a","b","c") ! upper-case(.)


> Many ideas, and a lot of work to get this specified. We could continue
> to discuss the new feature requests in the EXPath/EXQuery Github
> repositories or in the Wiki of the W3 EXPath Community Group; what do
> you think?
>
> https://www.w3.org/community/expath/wiki/Main_Page
> https://github.com/expath/expath-cg
> https://github.com/exquery/exquery

Hmmm. I like the Pull Request model that we have been using for
working on EXPath Module specs. I think that has worked quite well.

What do you think of this idea - https://github.com/expath/xpath-ng

Christian Grün

unread,
Oct 15, 2018, 8:15:13 AM10/15/18
to EXPath
> Interesting idea. I wonder if that might cause confusion with existing
> code, especially that code that is not well formatted.

So this might be a good occasion to get the code properly formatted ;)
I would hope there is not too much confusion because multiple shorted
"if" expressions need to be separated with commas in order to be
syntactically valid (but I might be wrong?).

Some example for possible use cases (some are driven by
non-deterministic functions, which do something, but do not yield any
result):

if (doc-available($doc)) then doc($doc),
if (file:exists($file)) then file:delete($file),
if (permissions:valid($user)) then <html>Welcome!</html>

> Another suggestion (although not better or worse) is to instead
> add "ifne", read as "if non empty":

The main difference would be that the "if" expression checks for the
effective boolean value:

if(false()) then B → ()
ifne(false()) then B → B

> Erm... I think I am missing some subtly here, but isn't this just:
> ("a","b","c") ! upper-case(.)

You are right of course ;) The syntax would e.g. be handy if we have
lists of operations, and if some of the operations require an
item-by-item processing:

let $increment := function($n) { $n + 1 }
return (
(1 to 10)
=!> $inc() (: or ==>, !>, ..)
=> sum()
)

The current writing would be something like:

let $increment := function($n) { $n + 1 }
return (
(1 to 10)
=> (function($v) { $v ! $increment(.) })()
=> sum()
)

But it’s not that trivial to get this specified. While the arrow
operator results in a simple function call, the proposed feature would
require a looped invocation of the addressed function.

Christian Grün

unread,
Oct 15, 2018, 12:04:41 PM10/15/18
to EXPath
> Hmmm. I like the Pull Request model that we have been using for
> working on EXPath Module specs. I think that has worked quite well.
>
> What do you think of this idea - https://github.com/expath/xpath-ng

I overlooked this one; that was quick, thank you! I hope I’ll manage
to add some of my suggestions later this week.

Kurt Cagle

unread,
Oct 15, 2018, 2:27:26 PM10/15/18
to exp...@googlegroups.com

I would love to see template literals implemented in XQuery. ATVs are similar, but being able to do something like:

 

let $person := <person><name>Jane Doe</name><age>25</age></person>

let $msg := `%{$person/name} is %{$person/age} years old.`

return $msg

  • “Jane Doe is 25 years old.”

 

would be REALLY powerful, especially with context operators:

 

let $msgTemplate = function($person as node()) as string* { `%{$person/name} is %{$person/age} years old.`}

let $persons :=  <persons>

     <person><name>Mike Myers</name><age>55</age></person>

     <person><name>Shannon Lee</name><age>17</age></person>

<persons>

return $persons/person!$msgTemplate(.)

  • (“Mike Myers is 55 years old.”,”Shannon Lee is 17 years old.”)

 

 

Sent from Mail for Windows 10

--

Christian Grün

unread,
Oct 15, 2018, 2:32:07 PM10/15/18
to EXPath
Hi Kurt,

The XQuery 3.1 string constructor should already meet your requirements:

let $msgTemplate := function($person as node()) as xs:string* {
``[`{ $person/name }` is `{ $person/age }` years old.]``
}
let $persons :=
<persons>
<person><name>Mike Myers</name><age>55</age></person>
<person><name>Shannon Lee</name><age>17</age></person>
</persons>
return $persons/person ! $msgTemplate(.)

Cheers,
Christian



On Mon, Oct 15, 2018 at 8:27 PM Kurt Cagle <kurt....@gmail.com> wrote:
>
> I would love to see template literals implemented in XQuery. ATVs are similar, but being able to do something like:
>
>
>
> let $person := <person><name>Jane Doe</name><age>25</age></person>
>
> let $msg := `%{$person/name} is %{$person/age} years old.`
>
> return $msg
>
> “Jane Doe is 25 years old.”
>
>
>
> would be REALLY powerful, especially with context operators:
>
>
>
> let $msgTemplate = function($person as node()) as string* { `%{$person/name} is %{$person/age} years old.`}
>
> let $persons := <persons>
>
> <person><name>Mike Myers</name><age>55</age></person>
>
> <person><name>Shannon Lee</name><age>17</age></person>
>
> <persons>
>
> return $persons/person!$msgTemplate(.)
>
> (“Mike Myers is 55 years old.”,”Shannon Lee is 17 years old.”)
>
>
>
>
>
>

Loren Cahlander

unread,
Oct 15, 2018, 3:45:13 PM10/15/18
to EXPath, Loren Cahlander, Markus Flatscher
Hello everyone,

I will try to take time this weekend to add the syntax of the various implementations of XQuery into the processing of xqDoc.

I would appreciate if people could add various XQuery scripts in the src/test/resources/XQuery in https://github.com/lcahlander/xqdoc-core to test all of the syntax extensions.  I would also appreciate many test cases for XQuery 3.1 syntax, so that I can make sure that the xqdoc:invoke and xqdoc:ref-variable are properly generated for all implementations.

Thanks,
Loren
signature.asc

Loren Cahlander

unread,
Oct 15, 2018, 3:52:34 PM10/15/18
to EXPath, Loren Cahlander, Markus Flatscher
Here is the view of the xqDoc schema:

signature.asc

Loren Cahlander

unread,
Oct 15, 2018, 4:00:43 PM10/15/18
to EXPath, Loren Cahlander, Markus Flatscher
My apologies.  The view does not include the annotations.  here is the XSD for xqDoc.
xqdoc-1.0.01132014.xsd
signature.asc

Loren Cahlander

unread,
Oct 15, 2018, 4:32:42 PM10/15/18
to EXPath, Loren Cahlander, Markus Flatscher
Can we have a conference call to discuss these?  I am open most times.

On Oct 15, 2018, at 4:00 PM, Loren Cahlander <loren.c...@gmail.com> wrote:

My apologies.  The view does not include the annotations.  here is the XSD for xqDoc.
<xqdoc-1.0.01132014.xsd>


On Oct 15, 2018, at 3:52 PM, Loren Cahlander <loren.c...@gmail.com> wrote:

Here is the view of the xqDoc schema:

<PastedGraphic-1.png>
signature.asc
Reply all
Reply to author
Forward
0 new messages