qt4cg / qtspecs

QT4 specifications
https://qt4cg.org/
Other
27 stars 15 forks source link

Extend `fn:doc`, `fn:collection` and `fn:uri-collection` with options maps #1021

Open line-o opened 4 months ago

line-o commented 4 months ago

fn:doc, fn:collection and fn:uri-collection currently expect only a single argument, a URI.

There is no way of adding additional parameters to those functions.

Several implementations of XPath have worked around that limitation by

  1. passing of parameters via query string as part of the URI:

  2. create custom functions in other namespaces to add an options map as a second parameter

While both approaches do work well, they do fall flat in terms of interoperability and discoverability. A script written for Saxon leveraging saxon:doc will not work on baseX in vice versa even though they offer options with some overlap. And a developer looking at the language specification will not discover that these options even exist.

I would like to add a second signature to the above functions with an options map as a second argument.

fn:doc($href as xs:string?) as document-node()?
fn:doc($href as xs:string?, $options as map(xs:string, *)? := ()) as document-node()?

NOTE: Looking at the other two functions below I believe the first parameter should be defined as $href as xs:string? := ()

fn:collection( $uri as xs:string? := ()) as item()*
fn:collection( $uri as xs:string? := (), $options as map(xs:string, *)? := ()) as item()*
fn:uri-collection( $uri as xs:string? := ()) as xs:anyURI*
fn:uri-collection( $uri as xs:string? := (), $options as map(xs:string, *)? := ()) as xs:anyURI*

Since a lot of those options depend on the current runtime most of them will be "free" options. This will also help us get to a specification quickly and circumvent long infighting about some very specific details.

I do see, however, a good chance of specifying a small set of options that would work across implementations.

Possible standard options

For fn:doc

For collection and uri-collection I see the following:

This would bring the above functions to follow a pattern developers are already familiar with (see fn:serialize and others)

Thanks for initial input by @ChristianGruen, Liam Quin and @michaelhkay

michaelhkay commented 4 months ago

See also issue #490 and issue #305

michaelhkay commented 4 months ago

Other options related to XML parsing include:

line-o commented 1 month ago

Related: #285

line-o commented 3 weeks ago

I am in the process of writing a draft to extend fn:doc with an options argument. If we were to specify and thus allow other formats than XML at least some of these would not return a document-node() but rather a function item. For JSON and CSV we would ideally just return the result of parse-json and parse-csv.

That would change the return type of fn:doc() to ( document-node() | array(*) | map(*) )?

Would this be considered a change that breaks backwards compatibility?

line-o commented 3 weeks ago

I did think about doc("/my/example/api", { "format": "json" }) to return a document-node() containing the parse result transformed to XML. It just seems unintuitive to me.

michaelhkay commented 3 weeks ago

It wouldn't break backwards compatibility to widen the result type (we did that with fn:collection()) but I'm not sure it's a good idea. A new function resource() that handles different kinds of resource might be better.

Perhaps resource("/my/example/api", {"content-type": "application/json"}) ?

line-o commented 3 weeks ago

That is an interesting approach. I would still want to see fn:doc to have an options parameter with the properties we gathered here. This new function should have its separate issue in order for us to be able to close this one once the required changes are merged.