- From: Jeni Tennison <jeni@jenitennison.com>
- Date: Sat, 19 May 2007 22:13:27 +0200
- To: public-xml-processing-model-wg@w3.org
The p:http-request discussion highlighted the fact that it is currently
impossible to use an input XML document to set the parameters on a
transformation. If you, as the pipeline author, know the parameters on a
stylesheet in advance, then you can access them individually to build up
a parameter set based on values in an XML document. However, if you
don't know them in advance then you can't create an (input)
configuration file for your pipeline looking like:
<my:config>
<my:stylesheet>
<!-- put your stylesheet URI here -->
</my:stylesheet>
<my:params>
<!-- put your stylesheet parameters here, in the form -->
<!-- <my:param name="..." value="..." /> -->
</my:params>
</my:config>
I can imagine a number of (unusual, but real world) processes where this
might be useful: pipelines that perform unit tests on XSLT stylesheets,
or run them a number of times to get performance information, or do some
pre-processing of the stylesheet before it gets run, or do some pre- or
post-processing of the source document before transforming with a
user-defined stylesheet, and so on.
It wouldn't bother me if this was hard. It does bother me that it's
impossible.
Given that this is an unusual case and the requirement for parameter
sets is an unusual case, I wonder if they can be solved through the same
mechanism, leaving the majority cases absolutely transparent.
Here's a possibility:
1. We introduce the concept of "parameter ports". Parameter ports are
just like normal input ports (and are added to the set of readable
ports), but always expect a single document that must contain a
<c:parameters> element that contains any number of <c:parameter>
elements with name, namespace, and value attributes. They are defined
with a <p:input> with parameters="yes".
2. All container steps have at least one parameter port. If they don't
specify one explicitly, they have a default parameter port named
'parameters'.
3. We remove the concept of in-scope parameters. Instead, there is the
concept of the "default readable parameter port", which is similar to
the "default readable port". If there is only one parameter port
specified (implicitly or explicitly) on a step container, that becomes
the default readable parameter port for its contained steps.
4. The document supplied to a parameter port can be supplied explicitly
in one of two ways:
(a) in the normal way, through a <p:input> in the step invocation
whose port name is that of a parameter port
(b) constructed from <p:parameter> elements used in the step
invocation; if there's more than one parameter port on the step then an
optional port attribute indicates which one the parameter goes to
If no document is supplied explicitly, the source is the default
readable parameter port.
5. We remove <p:import-parameters>.
Some examples:
--------------
A. Basic use: Henry's example:
> [invoke pipeline impl] my.xpl debug=1 < foo.xml
my.xpl:
<p:pipeline>
<p:xslt>
<p:input port="stylesheet">
<p:inline>
<xsl:stylesheet>
<xsl:param name="debug">0</xsl:param>
. . .
works because the <p:pipeline> has an (undeclared) parameter input port
that accepts the parameter passed from the command line and creates a
<c:parameters> document from them; that document gets passed to the
parameter port on <p:xslt>.
B. Parameter supplied as option:
<p:pipeline>
<p:input port="source" />
<p:option name="debug" value="false" />
<p:xslt>
<p:input port="stylesheet">...</p:input>
<p:parameter name="debug" select="$debug" />
</p:xslt>
</p:pipeline>
Here, the parameter document on the <p:xslt> step's parameter port is
constructed from the <p:parameter> element. If the $debug option isn't
set it will look like:
<c:parameters>
<c:parameter name="debug" value="false" />
</c:parameters>
C. Passing a subset of parameters:
<p:pipeline name="pipe">
<p:input port="source" />
<p:xslt>
<p:input port="stylesheet">...</p:input>
<p:parameter name="foo"
select="/c:parameters/c:parameter[@name = 'foo']">
<p:pipe step="pipe" port="parameters" />
</p:parameter>
</p:xslt>
</p:pipeline>
or, if you need more than one:
<p:pipeline name="pipe">
<p:input port="source" />
<p:viewport name="filter-parameters" match="c:parameter">
<p:viewport-source>
<p:pipe step="pipe" port="parameters" />
</p:viewport-source>
<p:matching-documents>
<p:option name="test"
value="/c:parameter/@name = 'foo' or
/c:parameter/@name = 'bar'" />
</p:matching-documents>
</p:viewport>
<p:xslt>
<p:input port="source">
<p:pipe step="pipe" port="source" />
</p:input>
<p:input port="stylesheet">...</p:input>
<p:input port="parameters">
<p:pipe step="filter-parameters" port="result" />
</p:input>
</p:xslt>
</p:pipeline>
D. Supplying parameters in config files:
<p:pipeline name="pipe">
<p:input port="source" />
<p:input port="config" />
<p:group name="extract-parameters">
<p:output port="result" />
<p:rename>
<p:input port="source" select="/my:config/my:params">
<p:pipe step="pipe" port="config" />
</p:input>
<p:option name="match" value="p:params" />
<p:option name="name" value="c:parameters" />
<p:rename>
<p:rename>
<p:option name="match" value="p:param" />
<p:option name="name" value="c:parameter" />
<p:rename>
</p:group>
<p:load name="load-stylesheet">
<p:option name="href" select="/my:config/my:stylesheet">
<p:pipe step="pipe" port="config" />
</p:option>
</p:load>
<p:xslt>
<p:input port="source">
<p:pipe step="pipe" port="source" />
</p:input>
<p:input port="stylesheet">
<p:pipe step="load-stylesheet" port="result" />
</p:input>
<p:input port="parameters">
<p:pipe step="extract-parameters" port="result" />
</p:input>
</p:xslt>
</p:pipeline>
£. Supplying two sets of parameters:
<p:pipeline name="pipe">
<p:input port="source" />
<p:input port="preprocess" />
<p:input port="preprocess-params" parameters="yes" />
<p:input port="postprocess" />
<p:input port="postprocess-params" parameters="yes" />
...
<p:xslt>
<p:input port="stylesheet">
<p:pipe step="pipe" port="preprocess" />
</p:input>
<p:input port="parameters">
<p:pipe step="pipe" port="preprocess-params" />
</p:input>
</p:xslt>
...
<p:xslt>
<p:input port="stylesheet">
<p:pipe step="pipe" port="postprocess" />
</p:input>
<p:input port="parameters">
<p:pipe step="pipe" port="postprocess-params" />
</p:input>
</p:xslt>
</p:pipeline>
The advantages of this approach are that it draws on existing, familiar,
mechanisms rather than introducing new ones, and thus is very powerful
and flexible, but retains usability and transparency for simple cases.
Thoughts?
Jeni
--
Jeni Tennison
http://www.jenitennison.com
Received on Sunday, 20 May 2007 05:24:33 UTC