- From: Norman Walsh <ndw@nwalsh.com>
- Date: Fri, 25 May 2007 05:50:43 -0400
- To: public-xml-processing-model-wg@w3.org
- Message-ID: <87y7jdnsek.fsf@nwalsh.com>
What's wrong with the status quo?
1. Having every step inherit every in-scope parameter is too coarse.
It requires the least syntax (i.e., nearly none) but invites users
to pass parameters that they didn't intend to steps that may change
behavior on that basis.
2. The inability to group parameters means it's very difficult to
select which parameters go to which steps. Using QNames avoids name
collisions, but using the namespace name as a grouping mechanism
interferes with steps that can accept parameters with arbitrary
QNames
3. It's not possible to compute parameters dynamically.
Personally, I consider solving problems 1 and 2 critical. Solving 3
would be nice, but I could live without it in V1.
What's "the simplest thing that could possibly work?"
1. No more automatic inheritance. That was easy :-) It no longer makes
any sense to allow p:parameter on compound steps.
2. Add a grouping mechanism. What do parameter groups remind me of?
XSLT attribute sets:
<p:parameter-set
name = NCName>
(p:parameter*)
</p:parameter-set>
For V1, I propose that p:parameter-set be allowed only as a child
of p:pipeline.
Having sets isn't very useful if you can't use them, so we also
need @use-parameter-sets on steps. (For steps not in the pipeline
namespace, that's spelled @p:use-parameter-sets.)
The ability to group parameters gives the pipeline author control
over all the parameters *except* those that are passed to the
pipeline (either by the application, e.g., from the command line
or by the invocation of the pipeline from some other pipeline).
There are a few ways we could address this, the simplest that
occurs to me is to allow "#default" as a parameter set name. It
means "all the parameters passed to the p:pipeline", which might be
the empty set.
Now I suppose a user might want to merge parameter-sets, just like
they can merge attribute-sets, so perhaps we could allow
@use-parameter-sets on p:parameter-set. If we do, then I think
the priority (for determining what to do with name collisions) should
be that the *used sets* have higher priority. That's possibly
counter-intuitive, but it means that in:
<p:parameter-set use-parameter-sets="#default">
<p:parameter name="output-method" value="html"/>
</p:parameter-set>
The output-method parameter passed to the pipeline, if there was
one, gets priority over the local one. Otherwise, merging with
#default isn't very useful.
If several names are listed in @use-parameter-sets, then they're
merged in the order given with the last definition having
priority. In a step, local, explicit p:parameter elements take
priority.
3. We could allow (p:empty|p:inline|p:pipe|p:document)* as a child of
p:parameter-set. It would be an error if any documents read inside
a p:parameter-set were not empty and not c:parameters containing
c:parameter elements.
If we do this, we also need to make it a dynamic error if a p:pipe
points to a step that (directly or indirectly) uses the parameter
set being defined. But that's no harder than the existing
circularity detection that implementations already have to do.
What does this mean?
Consider the simplest case:
<p:pipeline>
...
<p:xslt>
<p:input port="source">...</p:input>
<p:input port="stylesheet">...</p:input>
</p:xslt>
</p:pipeline>
Today, any parameters passed to the pipeline are automatically
available to the XSLT step. To obtain that behavior under this
proposal, the pipeline would have to be changed as follows:
<p:pipeline>
...
<p:xslt use-parameter-sets="#default">
<p:input port="source">...</p:input>
<p:input port="stylesheet">...</p:input>
</p:xslt>
</p:pipeline>
If there were any legacy pipelines, and those legacy pipelines relied
on parameters set on p:group elements scoping the parameters used inside
the group, they'd have to be changed from:
<p:pipeline>
...
<p:group>
<p:option name="baz" select="concat($moo,'-1')"/>
<p:parameter name="foo" value="bar"/>
<p:xslt>
<p:input port="source">...</p:input>
<p:input port="stylesheet">...</p:input>
<p:parameter name="base-name" select="$baz"/>
</p:xslt>
<px:something-else/>
</p:group>
</p:pipeline>
to something like this:
<p:pipeline>
<p:parameter-set name="group1" use-parameter-sets="#default">
<p:parameter name="foo" value="bar"/>
</p:parameter-set>
...
<p:group>
<p:option name="baz" select="concat($moo,'-1')"/>
<p:xslt use-parameter-sets="group1">
<p:input port="source">...</p:input>
<p:input port="stylesheet">...</p:input>
<p:parameter name="base-name" select="$baz"/>
</p:xslt>
<px:something-else p:use-parameter-sets="group1"/>
</p:group>
</p:pipeline>
If we allow parameter sets to be computed, then we can also say:
<p:pipeline>
<p:parameter-set name="global">
<p:pipe port="load-global" step="result"/>
</p:parameter-set>
<p:try name="load-global">
<p:group>
<p:output port="result"/>
<p:load>
<p:option name="href" value="~/.globals.xml"/>
</p:load>
</p:group>
<p:catch>
<p:output port="result"/>
<p:identity>
<p:input port="source">
<p:inline>
<c:parameters/>
</p:inline>
</p:input>
</p:identity>
</p:catch>
</p:try>
<p:xslt use-parameter-sets="global #default">
...
</p:xslt>
</p:pipeline>
It seems to me that with this proposal, the semantics of parameter
passing are much more explicit (and much less risky) and the syntactic
overhead is low.
Be seeing you,
norm
--
Norman Walsh <ndw@nwalsh.com> | A wonder is often expressed that the
http://nwalsh.com/ | greatest criminals look like other men.
| The reason is that *they are like other
| men in many respects.*-- Hazlitt
Received on Friday, 25 May 2007 09:50:55 UTC