More thoughts on the transform() function

All,

When XForms is lagging behind XPath, we find ourselves trying to reinvent
things that have been already done. This is the case with the `transform()`
function. So I wonder how much effort we should be spending on this given
that there is such a function in XPath 3 and it does everything we need.

The thinking so far has been that we don't mandate XPath 3, and it would be
nice if we could provide `transform()` anyway.

I think that is a valid approach, but only if:

1. The use cases for `transform()` are really strong.
2. It is reasonably easy to provide a `transform()` function without XPath
3 support.

Otherwise, I am tempted to say that efforts would be better spent updating
to XPath 3.

So far the possibilities to add support include:

- providing a simplified `transform()` function, which e.g. doesn't support
multiple inputs/outputs
- trying to use `xf:submission` (but it is unclear how to do that and
whether that would be any easier)
- supporting what XPath 3 supports, but without XPath 3 maps
    - with sequences
    - embedding values and documents within XML

The last 2 sub-options have issues and in the end they are not quite
equivalent to the XPath 3 version.

I mentioned during the last call last a 3rd possibility: provide very
minimal support for maps, namely:

- a way to create an empty map (XPath doesn't seem to have a `map:empty()`)
- `map:put()`
- `map:get()`
- `map:keys()`

With this, if your XPath implementation supports custom functions and
custom objects, you could create and pass a map to `transform()`, get a map
back, and have something identical to the XPath 3 function.

With XPath 3, you would typically use the native map syntax:

    let $result := transform(
        map {
            "stylesheet-uri" : "render.xsl",
            "source-node"    : doc('test.xml')
        }
    )
    return $result?output//body

With XForms 2/XPath 2, you would instead use the functions above to create
a new map:

    map:get(
        transform(
            map:put(
                map:put(
                    map:empty(),
                    "stylesheet-uri",
                    "render.xsl"),
                "source-node",
                doc('test.xml'
            )
        ),
        "output"
    )//body

The requirement is 4 small functions backing a basic implementation of
maps, plus a function to create an empty map. The result would be
source-compatible with the XPath 3 version, modulo maybe the namespaces for
the `map:` functions.

It would do the job and be relatively usable, but is it worth it?

Regards,

-Erik

Received on Wednesday, 1 June 2016 03:42:39 UTC