- From: Jeni Tennison <jeni@jenitennison.com>
- Date: Fri, 01 Jun 2007 19:56:14 +0100
- To: public-xml-processing-model-wg@w3.org
Norman Walsh wrote: > / Jeni Tennison <jeni@jenitennison.com> was heard to say: > [...] > | and call this new pipeline in the same way as before: > | > | <my:matching-documents xmlns:my="http://www.example.com/ns/jeni"> > | <p:option name="test" value="/my:foo[@bar = $bar]" /> > | </my:matching-documents> > | > | The value '/my:foo[@bar = $bar]' is passed as the value of the test > | option to <jt:matching-documents> as a string. But in my pipeline, > | where <p:matching-documents> is called, there's no binding for the > | 'my' prefix, nor for the $bar in-scope option, so the pipeline fails. > > Perhaps we should allow options to be passed into called pipelines. At > the moment, it's only forbidden by the special rules for constructing > the p:pipeline environment. We could fix that. > > Then, if $bar is in scope for the pipeline that calls > my:matching-documents, it would be in scope for the step that > evaluates it. Options would be passed down. But then they shouldn't be options. The distinguishing feature of options is that they are predefined, and if you're passing in name/value pairs from the calling pipeline, then those pairs can't be known in advance. No, what's needed here is for <my:matching-documents> and the other similar steps to define mappings (parameter sets) for namespaces and for variable bindings, and to use those when evaluating expressions and patterns. You want a proposal? 1. We define two markup languages that are pretty similar: a. <c:option> documents, each having a required 'name', optional 'namespace' (defaults to an empty string / no namespace) and required 'value' attributes. b. <c:namespace> documents, each having 'prefix' (which can be empty) and 'uri' attributes. Each of these elements can have any number of extension attributes. 2. We define a new attribute on <p:input> declarations, called 'default', whose values can be "current-source", "in-scope-options" or "in-scope-namespaces". The semantics are that if the given input port isn't given an explicit binding, it has an implicit binding based on the value of the default attribute: * default="current-source" means that it's bound to the default readable port * default="in-scope-options" means that it's bound to a sequence of <c:option> documents, one for each of the in-scope options at the point the step is called * default="in-scope-namespaces" means that it's bound to a sequence of <c:namespace> documents, one for each of the in-scope namespaces at the point the step is called The default value for the 'default' attribute is 'current-source'. If default="in-scope-options" or default="in-scope-namespaces" then the default value of the 'sequence' attribute is 'yes'. In addition, if you call a step and supply a port with default="in-scope-options" or default="in-scope-namespaces" with a sequence of <c:option>/<c:namespace> documents, they are filtered such that the last <c:option>/<c:namespace> with a given name/namespace or prefix is the only one present in the sequence that's received by the called step. For example, the <p:xslt1> step is defined as: <p:declare-step type="p:xslt1"> <p:input port="source" /> <p:input port="stylesheet" /> <p:input port="parameters" default="in-scope-options" /> </p:declare-step> If you call it with: <p:xslt1> <p:input port="parameters"> <p:inline><c:option name="opt1" value="val1" /></p:inline> <p:inline><c:option name="opt2" value="val2" /></p:inline> <p:inline><c:option name="opt1" value="val3" /></p:inline> </p:input> </p:xslt1> then the parameters opt1=val3 and opt2=val2 will be passed to the stylesheet. 3. We provide two components: <p:option-documents> and <p:namespace-documents> which create <c:option> or <c:namespace> documents on their result port, based on the source that they're passed (explicitly or implicitly). Their signatures are: <p:declare-step type="p:option-documents"> <p:input port="source" default="in-scope-options" /> <p:output port="result" sequence="yes" /> </p:declare-step> <p:declare-step type="p:namespace-documents"> <p:input port="source" default="in-scope-namespaces" /> <p:output port="result" sequence="yes" /> </p:declare-step> 4. For each step in the standard step library that have options containing expressions or patterns, we define extra inputs that default to in-scope-options and in-scope-namespaces, providing variable and namespace bindings for evaluating the expression or pattern. For example, p:matching-documents would be declared as: <p:declare-step type="p:matching-documents"> <p:input port="source" sequence="yes" /> <p:input port="variable-bindings" default="in-scope-options" /> <p:input port="namespace-bindings" default="in-scope-namespaces" /> <p:output port="result" sequence="yes" /> <p:option name="test" required="yes" /> </p:declare-step> 5. We provide a p:in-scope-namespaces built-in step with the following signature: <p:declare-step type="p:in-scope-namespaces"> <p:input port="source" /> <p:output port="result" sequence="yes" /> </p:declare-step> The step returns a <c:namespace> element for each namespace in-scope on the document element of the source document. This step supports the use of XPath expressions that are held within source documents. [6. We rename 'option' to 'parameter' :)] See examples below to see how this fits together. > | If we had the time/will to do something about this, it would mean > | having a way of capturing the namespace bindings and in-scope options > | that are passed through to the pipeline step, and passing them on > | (selectively) to the contained steps. We could do it in the same way > | as I've suggested for parameters, since really it's the same problem. > > That's trickier. It doesn't appear to be solvable in the general case: > > <p:pipeline name="jt:matching-documents" > xmlns:jt="http://www.example.com/ns/jeni"> > <p:input port="source" sequence="yes" /> > <p:output port="result" sequence="yes" /> > <p:option name="test" required="yes" /> > > <p:option name="mytest" select="$test|my:bar" > xmlns:my="http://nwalsh.com/ns/norm"/> > > <p:matching-documents> > <p:option name="test" select="$mytest" /> > </p:matching-documents> > </p:pipeline> > > Now this call > > <my:matching-documents xmlns:my="http://www.example.com/ns/jeni"> > <p:option name="test" value="/my:foo[@bar = $bar]" /> > </my:matching-documents> > > can't (practically) be expected to work. No, defining namespaces on individual options can't reasonably be expected to work. If you do that, you lose. I'm happy for that to be the case, if there's a way of defining namspaces on a *step* and having them be honoured. Jeni --- EXAMPLES: 1. By default, the in-scope options and namespaces get passed to a step, and it will use those to evaluate XPath expressions. So doing: <p:pipeline name="my:call" xmlns:my="http://www.example.com/ns/jeni"> <p:input port="source" sequence="yes" /> <p:output port="result" sequence="yes" /> <p:option name="bar" required="yes" /> <p:matching-documents> <p:option name="test" value="/my:foo[@bar = $bar]" /> </p:matching-documents> </p:pipeline> will work transparently. 2. If the pipeline is passed an option that is a XPath, which it just passes on to an invoked step, as in: <p:pipeline name="jt:matching-documents" xmlns:jt="http://www.example.com/ns/jeni"> <p:input port="source" sequence="yes" /> <p:output port="result" sequence="yes" /> <p:option name="test" required="yes" /> <p:matching-documents> <p:option name="test" select="$test" /> </p:matching-documents> </p:pipeline> then to get the correct interpretation of the test option (based on the namespaces and options in-scope at the invocation of jt:matching-documents), you would do: <p:pipeline name="jt:matching-documents" xmlns:jt="http://www.example.com/ns/jeni"> <p:input port="source" sequence="yes" /> <p:input port="variable-bindings" default="in-scope-options" /> <p:input port="namespace-bindings" default="in-scope-namespaces" /> <p:output port="result" sequence="yes" /> <p:option name="test" required="yes" /> <p:matching-documents> <p:input port="variable-bindings"> <p:pipe source="variable-bindings" /> </p:input> <p:input port="namespace-bindings"> <p:pipe source="namespace-bindings" /> </p:input> <p:option name="test" select="$test" /> </p:matching-documents> </p:pipeline> 3. The general case is that all in-scope options are passed to a stylesheet. If all your options go straight through to parameters, you don't even have to specify the parameters port: <p:pipeline name="my:summary"> <p:input port="source" /> <p:output port="result" /> <p:option name="view" value="plain" /> <p:option name="groups" value="country" /> <p:xslt1> <p:input port="stylesheet"> <p:document href="summary.xsl" /> </p:input> </p:xslt1> </p:pipeline> summary.xsl will be passed the parameters view and groups, since these are the in-scope options. 4. One way to limit the parameters that are actually passed into XSLT would be to create a document based on the in-scope options, and filter that. For example: <p:option-documents name="get-parameters" /> <p:xslt1> ... <p:input port="parameters" select="/c:option[(@namespace = '' and (@name = 'foo' or @name = 'bar')) or @namespace = 'http://www.example.com/ns/foo']"> <p:pipe step="get-parameters" source="result" /> </p:input> </p:xslt1> would pass only the {}:foo, {}:bar and {http://www.example.com/ns/foo}:* parameters into the stylesheet. 5. Implementations should make it possible to bind in-scope options (and in-scope namespaces) from the command line. To take advantage of it, say to pass any command-line parameters into your XSLT stylesheet, you'd need to specify an input that captured them in the pipeline: <p:pipeline name="my:command-line-xslt"> <p:input port="source" /> <p:input port="stylesheet" /> <p:input port="parameters" default="in-scope-options" /> <p:output port="result" /> <p:xslt1> <p:input port="stylesheet"> <p:pipe source="stylesheet" /> </p:input> <p:input port="parameters"> <p:pipe port="parameters" /> </p:input> </p:xslt1> </p:pipeline> 6. Configuration documents like: <my:config xmlns:my="http://www.example.com/ns/my" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <my:filter test="/xhtml:html/xhtml:head/rdf:*" /> </my:config> can be used to configure pipelines: <p:pipeline name="my:configurable-filter" xmlns:my="http://www.example.com/ns/my"> <p:input port="source" sequence="yes" /> <p:input port="config" /> <p:output port="result" sequence="yes" /> <p:in-scope-namespaces name="test-namespaces"> <p:input port="source" select="/my:config/my:filter"> <p:pipe source="config" /> </p:input> </p:in-scope-namespaces> <p:matching-documents> <p:input port="source"> <p:pipe source="source" /> </p:input> <p:input port="namespace-bindings"> <p:pipe step="test-namespaces" source="result" /> </p:input> <p:option name="test" select="/my:config/my:filter/@test"> <p:pipe source="config" /> </p:option> </p:matching-documents> </p:pipeline> -- Jeni Tennison http://www.jenitennison.com
Received on Friday, 1 June 2007 18:56:27 UTC