Summary: How should variables be set?

Hi,

I want to summarise the arguments about how variables and parameters get
set. We have agreement that XPath 1.0 is used to set the values of
variables and parameters, and that input and intermediate documents can
provide information for those values. We then have two options:

A: Expressions are evaluated against either a single context node (the
root node of a input or intermediate document in the pipeline, indicated
by a 'context' or 'ref' attribute) or no context node (if no 'context'
or 'ref' attribute is given). Variable references in the XPath
expression are used to refer to the values of XProc variables and
parameters.

B: Expressions are evaluated with no context node. Variable references
in the XPath expression are used to refer to the values of XProc
variables and parameters, and to input and intermediate document sequences.

I prefer B to A for the following reasons:

1. With B, you can do things with document sequences (such as count
    the number of documents they contain or unioning two sequences)
    without needing custom components. See (a) for an example.

2. With B, you can much more easily select a subset of documents from a
    document sequence. See (b) for an example.

3. With B, you can compare information from two inputs in a less
    tedious way. See (c) for an example.

4. B gives a syntax and semantics that's more consistent between
    elements in the XProc language. This makes it easier to learn and
    understand.

5. B gives a syntax and semantics that's more consistent with XSLT. This
    makes it easier to learn and understand for XSLT users.

6. (I claim) B is not significantly harder to implement than A.

Cheers,

Jeni

---

Examples:

(a) Basing a condition on the number of documents provided in an input.

Syntax A:

   <p:pipeline>
     <p:input name="input" />
     ...
     <p:step name="p:count">
       <p:input name="input" ref="input" />
       <p:output name="output" label="count" />
     </p:step>
     <p:choose>
       <p:input name="count" ref="count" />
       ...
       <p:when context="count" test=". > 1">
         ...
       </p:when>
       ...
     </p:choose>
   </p:pipeline>

Syntax B:

   <p:pipeline>
     <p:input name="input" />
     ...
     <p:choose>
       <p:input name="input" select="$input" />
       ...
       <p:when test="count($input) > 1">
         ...
       </p:when>
       ...
     </p:choose>
   </p:pipeline>

(b) Selecting a subset of the documents in a document sequence.

Syntax A: (Is there a simpler way?)

   <p:pipeline>
     <p:input name="input" />
     ...
     <p:for-each ref="input">
       <p:input name="input" />
       <p:output name="output" label="filtered" ref="output" />
       <p:choose>
         <p:input name="input" ref="input" />
         <p:output name="output" ref="output" />
         <p:when context="input" select="/svg:svg">
           <p:step name="p:identity">
             <p:input name="input" ref="input" />
             <p:output name="output" label="output" />
           </p:step>
         </p:when>
         <p:otherwise>
           <p:step name="p:empty-sequence">
             <p:output name="output" label="output" />
           </p:step>
         </p:otherwise>
       </p:choose>
     </p:for-each>
     <p:step name="my:process">
       <p:input name="input" ref="filtered" />
       ...
     </p:step>
     ...
   </p:pipeline>

Syntax B:

   <p:pipeline>
     <p:input name="input" />
     ...
     <p:step name="my:process">
       <p:input name="input" select="$input[/svg:svg]" />
       ...
     </p:step>
     ...
   </p:pipeline>

(c) Comparing two inputs

Syntax A:

<p:pipeline>
   <p:input name="authors" />
   <p:input name="books" />
   ...
   <p:choose>
     <p:input name="authors" ref="authors" />
     <p:input name="books" ref="books" />
     ...
     <p:variable name="authors" context="authors" select="." />
     <p:when context="books"
             test="/books/book/authors/author = $authors/authors/author">
       ...
     </p:when>
     ...
   </p:choose>
   ...
</p:pipeline>

Syntax B:

<p:pipeline>
   <p:input name="authors" />
   <p:input name="books" />
   ...
   <p:choose>
     <p:input name="authors" ref="authors" />
     <p:input name="books" ref="books" />
     ...
     <p:when test="$books/books/book/authors/author =
                   $authors/authors/author">
       ...
     </p:when>
     ...
   </p:choose>
   ...
</p:pipeline>

-- 
Jeni Tennison
http://www.jenitennison.com

Received on Wednesday, 31 May 2006 09:18:52 UTC