On the train ride home Monday night, I decided to do something different. Implementor's prerogative.
The XProc specification states that all variables, options, and parameters are string values. On the whole, I think this is a useful simplification:
All of the options used by the standard atomic steps have convenient string representations: they don't need more complex structures.
In an XPath 1.0 implementation there are only a few data types anyway (remember, there was a time when we thought we might finish before the XSLT/XQuery WGs). [Ah, optimism! -ed ]
Using strings simplifies serialization issues for steps like
But it's frustrating in one particular area, XSLT parameters and XQuery external variables can have more complex values. The fact that XProc doesn't support this means that there are some stylesheets and queries that can't be fully supported by XProc.
Early on, I proposed that we allow parameters at least to contain either strings or documents, but I couldn't get working group support for the idea. (I think they'll come around, but not in 1.0.)
I've wondered, ever since my idea got left on the cutting room floor, how hard it would be to support arbitrary XDM values in XProc.
So I implemented it.
Turns out it's not very hard at all.
I extended the
RuntimeValue object to preserve the original
XDM value of the expression instead of discarding it after
computing its string value. In
p:xquery, instead of using the string value for parameters
and external variables, respectively,
I use the XDM value. Everywhere else, I continue to use the string
value so this change has no impact on other atomic steps.
In compound steps, I made a change analagous to the changes for
p:xquery, when setting up the environment
for evaluating XPath expressions, I use the XDM values of options and
variables instead of the string values. This means that user-defined
pipelines can accept and use XDM values.
The hardest part, by far, was changing the
step and the interpretation of
to support an extended serialization for arbitrary XDM values.
All of which means that you can do things like this:
Back out in our main pipeline, we extract values from the configuration file and store them in variables. (We don't have to do this, of course, we could have computed the sequence directly with XPath expressions.)
Pay particular attention to the first value❸. This XPath expression selects a node; in standard XProc, this would automatically become a string. Using the general values extension, this will remain a node, which may not be what was intended.
Finally, we pass all of these values to the
as a sequence❻. In standard XProc, this sequence
would be collapsed into a single string value, but it will remain a
sequence if we use the general values extension.
Run through a standard XProc processor, here is the expected result:
We get the string value of all the variables, options,
and parameters with the
param-seq option compressed to
a single string value.
But if we enable the general values extension (with
-X general-values on the command line with
XML Calabash version
0.9.12), we get a
Here our sequence has been passed successfully and each of the individual values has been preserved all the way through to XSLT.
With the general values extension, XML Calabash does not implement XProc 1.0! It implements a closely related, but entirely non-standard language which you cannot expect to interoperate with other implementations.
There are still a few obvious weaknesses in this extension.
Implementing a non-standard extension is a bad thing. I probably should disable it completely.
There should be a mechanism (an
asattribute, probably) to selectively enable this behavior. This would also allow for type-checking the values passed around.
The serialization used by
p:parametersis incompletely supported. Although the serialization identifies the type of atomic values, the code which interprets this serialization ignores the types. Integers may go in, but strings come out.
This is an experimental feature. It may or may not survive over the long run. Comments most welcome.
Remember: if you enable this extension, you are not running a conformant XProc processor. Your gun, your bullet, your foot.