- From: Jeni Tennison <jeni@jenitennison.com>
- Date: Mon, 24 Jul 2006 12:38:48 +0100
- To: public-xml-processing-model-wg@w3.org
Norm Walsh wrote:
> A for-each looks like:
>
> for-each := ($over, $select?, $label, with-output, {body})
>
> Where $over identifies a stream over which the XPath expression in
> $select should be applied. The body of the element is applied to each
> node (or nodes) selected. The nodes are available as a a document
> (with the label $label) to the body of the for-each.
>
> The single with-output element (which must have the name 'result')
> identifies which output from the steps in the body is to be considered
> the output of each application.
>
> The result of the entire step is the sequence of results obtained from
> each application.
Some thoughts on for-each:
1. I think we need more than one with-ouput (or declare-output as we
have it now). The contained steps can produce multiple outputs; it seems
weird to lose those outputs. For example, say that the 'validate' step
produces a copy of the original document with defaulted & fixed
attributes/elements added, plus a set of errors/warnings from the
document. To validate each chapter and capture all the validated
documents and errors, you'd need:
<p:for-each select="//chapter" ref="#pipe/document" name="loop">
<p:declare-output port="validated" />
<p:declare-output port="errors" />
<p:step kind="validate" name="validate">
<p:input port="document" ref="#loop/#matched" />
<p:output port="validated" ref="#loop/validated" />
<p:output port="errors" ref="#loop/errors" />
</p:step>
</p:for-each>
2. Rather than using #loop/#matched (or something similar) to reference
the individual input documents, as in the above, I think we should let
the user provide names for them. A design like:
<p:for-each name="loop">
<p:declare-input port="chapter"
ref-each="#pipe/document"
select="//chapter" />
<p:declare-output port="validated" />
<p:declare-output port="errors" />
<p:step kind="validate" name="validate">
<p:input port="document" ref="#loop/chapter" />
<p:output port="validated" ref="#loop/validated" />
<p:output port="errors" ref="#loop/errors" />
</p:step>
</p:for-each>
would enable this. (The 'ref-each' attribute indicates that the input is
one that should be iterated over, rather than a normal input, to enable
other kinds of input to be declared too.)
3. If we adopted the above design, we *could* support joins. For
example, the following would transform each of the chapters in the
pipe's document input with each of the stylesheets in the pipe's
stylesheets input:
<p:pipeline name="pipe">
<p:declare-input port="document" />
<p:declare-input port="stylesheets" />
<p:declare-output port="results" />
<p:for-each name="loop">
<p:declare-input port="chapter"
ref-each="#pipe/document"
select="//chapter" />
<p:declare-input port="stylesheet"
ref-each="#pipe/stylesheets" />
<p:declare-output port="results" ref="#pipe/results" />
<p:step kind="xslt" name="transform">
<p:input port="document" ref="#loop/chapter" />
<p:input port="stylesheet" ref="#loop/stylesheet" />
<p:output port="result" ref="#loop/results" />
</p:step>
</p:for-each>
</p:pipeline>
You'd invoke it with something like:
<p:step kind="pipe">
<p:input port="document" href="book.xml" />
<p:input port="stylesheets"
href="docbook2html.xsl docbook2fo.xsl" />
<p:output port="result" />
</p:step>
The alternative is nested for-eaches, of course:
<p:pipeline name="pipe">
<p:declare-input port="document" />
<p:declare-input port="stylesheets" />
<p:declare-output port="results" />
<p:for-each name="loop1">
<p:declare-input port="chapter"
ref-each="#pipe/document"
select="//chapter" />
<p:declare-output port="results" ref="#pipe/results" />
<p:for-each name="loop2">
<p:declare-input port="stylesheet"
ref-each="#pipe/stylesheets" />
<p:declare-output port="results" ref="#loop1/results" />
<p:step kind="xslt" name="transform">
<p:input port="document" ref="#loop1/chapter" />
<p:input port="stylesheet" ref="#loop2/stylesheet" />
<p:output port="result" ref="#loop2/results" />
</p:step>
</p:for-each>
</p:for-each>
</p:pipeline>
which isn't too bad.
Cheers,
Jeni
--
Jeni Tennison
http://www.jenitennison.com
Received on Monday, 24 July 2006 12:58:49 UTC