<?xml version="1.0" encoding="UTF-8"?>
<?publication-root http://www.w3.org/XML/XProc/docs/?>
<?latest-version http://www.w3.org/XML/XProc/docs/langspec.html?>
<specification xmlns="http://docbook.org/ns/docbook"
	       xmlns:xlink="http://www.w3.org/1999/xlink"
	       xmlns:xi='http://www.w3.org/2001/XInclude'
	       xmlns:cs="http://www.w3.org/XML/XProc/2006/04/components#"
	       xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"
	       class="ed"
	       version="5.0-extension w3c-xproc"
	       role="editors-copy">
<info>
<title>XProc: An XML Pipeline Language</title>
<w3c-shortname>xproc</w3c-shortname>
<pubdate>2006-09-12</pubdate>

<bibliorelation type="isformatof"
		xlink:href="langspec.xml">XML</bibliorelation>

<bibliorelation type="replaces"
		xlink:href="ED-xproc-20060821"/>

<!-- what about prevlocs? -->

<authorgroup>
  <author>
    <personname>Norman Walsh</personname>
    <affiliation>
      <orgname>Sun Microsystems, Inc.</orgname>
    </affiliation>
    <email>Norman.Walsh@Sun.COM</email>
  </author>
</authorgroup>
  
<abstract>
<para>This document is a shell where ideas, points of consensus, and
early draft text is being collected. It does not necessarily represent
the consensus of the Working Group.</para>
</abstract>

<legalnotice role="status">

<para><emphasis>This section describes the status of this document at
the time of its publication. Other documents may supersede this
document. A list of current W3C publications and the latest revision
of this technical report can be found in the <link
xlink:href="http://www.w3.org/TR/">W3C technical reports index</link>
at http://www.w3.org/TR/.</emphasis></para>

<para>More boilerplate goes here…</para>
</legalnotice>
</info>

<section xml:id="introduction">
<title>Introduction</title>

<para>An XML Pipeline describes a sequence of operations to be
performed on a collection of input documents. Pipelines take zero or more
XML documents as their input and produce zero or more XML documents as
their output. Components in the pipeline <rfc2119>may</rfc2119>
read or write non-XML resources as well.</para>

<para>Each operation in a pipeline is performed by a component. Like
pipelines, components take zero or more XML documents as their input
and produce zero or more XML documents as their output. The inputs to
a component come from the web, from the pipeline document, from the inputs to the
pipeline itself, or from the outputs of other components in the pipeline. The outputs
from a component are either consumed by other components or are
outputs of the pipeline as a whole. Outputs may also be ignored.</para>

<para>This specification defines a standard component library,
<xref linkend="std-components"/>.
Pipeline implementations may support additional components as
well.</para>

<para><xref linkend="fig-xival"/> is a graphical representation of a
simple pipeline that performs XInclude processing and validation on a
document.</para>

<figure xml:id="fig-xival">
<title>A simple, linear XInclude/Validate pipeline</title>
<mediaobject>
<alt>A simple, linear XInclude/Validate pipeline</alt>
<imageobject>
<imagedata fileref="graphics/sch-xinclude-validate-pipeline.png"/>
</imageobject>
</mediaobject>
</figure>

<para>This is a pipeline that consists of two components, XInclude and
Validate. The pipeline itself has two inputs, “document” and “schema”.
How these inputs are connected to XML documents is implementation-defined.
The XInclude
component reads the pipeline input “Document” and produces a result
document. The Validate component reads the pipeline input “Schema” and
the output from the XInclude component and produces a
result document. The result of the validation is the result of the
pipeline, “Result Document”.
How pipeline outputs are connected to XML documents is
implementation-defined.</para>

<para><xref linkend="fig-style-proc"/> is a more complex example: it
performs schema validation with an appropriate schema and then styles
the validated document.</para>

<figure xml:id="fig-style-proc">
<title>A validate and transform pipeline</title>
<mediaobject>
<alt>A validate and transform pipeline</alt>
<imageobject>
<imagedata fileref="graphics/sch-transform.png"/>
</imageobject>
</mediaobject>
</figure>

<para>The heart of this example is the conditional. The standard “choose”
component evaluates an XPath expression over a test document. Based on the
result of that expression, one or another branch is evaulated.</para>

</section>

<section xml:id="pipeline-concepts">
<title>Pipeline Concepts</title>

<para><termdef xml:id="dt-pipeline">A <glossterm>pipeline</glossterm>
is an acyclic, directed graph of components connected together by
inputs and outputs.</termdef> A pipeline is itself a
<glossterm>component</glossterm> and must satisfy the constraints on
components.</para>

<para>The result of evaluating a pipeline is the result of evaluating
the components that it contains. A pipeline must behave as if it
evaluated each component each time it occurs. Unless otherwise
indicated, implementations <rfc2119>must not</rfc2119> assume that
components are functional (that is, that their output depends only on
their explicit inputs and parameters) or side-effect free.</para>

<section xml:id="steps">
<title>Steps, Step Containers, and Subpipelines</title>

<para>In a pipeline document, the components of a pipeline are represented
with steps. Each step represents one or more components and describes
how the component(s) it represents fit into the pipeline.</para>

<para>Many steps are simple, atomic representations of a single component.
An XSLT step, for example, represents an XSLT component; a validation step
rerpesents a validation component, etc. However, some steps include a description
of the component-level behavior that they instantiate in terms of additional
steps. <termdef xml:id="dt-step-container">A step which contains other steps
is called a <glossterm>step containers</glossterm>.</termdef>
<termdef xml:id="dt-contained-steps">The steps that occur inside another step
are called <glossterm>contained steps</glossterm>.</termdef>
</para>

<para>Some additional semantic rules apply to contained steps:</para>

<note role="editorial" xml:id="container-rules">
<para>Is this a good place/the right place for this kind of summary?</para>
</note>

<orderedlist>
<listitem>
<para>The contained steps can read input from the declared inputs of their
step container (or ancestor step containers).</para>
</listitem>
<listitem>
<para>The output of one component can only be connected to the input of another component
that is in the same step container.</para>
</listitem>
</orderedlist>

<para><termdef xml:id="dt-subpipeline">Any set of components,
instantiated from one or more steps or a set of contained steps forms
a <glossterm>subpipeline</glossterm>.</termdef> Subpipelines are most
often invoked by components that instantiate <glossterm>step
containers</glossterm>, where the collection of components
instantiated by the contained steps forms a subpipeline.</para>
</section>

<section xml:id="components">
<title>Components</title>

<para>Components are the basic computational units of a pipeline. <termdef
xml:id="dt-component">A <glossterm>component</glossterm> is a unit of XML
processing, such as XInclude or transformation.</termdef> Components may
perform arbitrary amounts of computation but they are indivisible from
the point of view of the pipeline that instantiates them.</para>

<para>Components have “ports” into which inputs and outputs are
connected. Each component has a number of input ports and a number of
output ports, all with unique names. A component may have zero input
ports and/or zero output ports. (All components have a standard output port
for reporting errors that does not have to be, and cannot be,
declared.)</para>

<para>Components have any number of parameters, all with unique names.
A component may have zero parameters.</para>

<para>All of the input ports of a component must be connected to
inputs. It is a <glossterm>static error</glossterm> if a component has
an input port which is not connected. Unconnected output ports are allowed;
any documents produced on those ports are simply discarded.</para>

<para><termdef xml:id="dt-signature">The <glossterm>signature</glossterm>
of a component is the set of inputs, outputs, and parameters that it
is declared to accept.</termdef>
<termdef xml:id="dt-matches">The instantiation of a component
<glossterm>matches</glossterm> its signature if and only if it specifies
an input for each declared input and it specifies no inputs that are not
declared, it specifies no outputs that are not declared, it specifies
a parameter for each parameter that is declared to be required, and it
specifies no parameters that are not declared.</termdef>
In other words, every input and required parameter must be specified
and only inputs, outputs, and parameters that are declared may be
specified. Outputs and optional parameters do not have to be
specified.</para>
</section>

<section xml:id="input-output">
<title>Inputs and Outputs</title>

<para>Although components are free to read and write non-XML resources,
what flows <emphasis>between</emphasis> components as
inputs and outputs are exclusively XML documents or sequences of XML
documents. Each XML document (or document in a sequence) must be a
well formed <biblioref linkend="REC-xml"/> or
<biblioref linkend="xml11"/> document. The inputs and outputs may be
implemented as sequences of characters, events, or object models, or any other
representation the implementation chooses.</para>

<note role="editorial" xml:id="xml11-optional">
<para>Is support for XML 1.1 optional?</para>
</note>

<para>It is a <glossterm>dynamic error</glossterm> if a non-XML
resource is produced on a component output or arrives on a component
input.</para>

<note role="editorial" xml:id="non-xml-not-detected">
<para>What about the cases where it's impractical to test for this error?</para>
</note>

<para>An implementation may make it possible for
a component to produce non-XML output, for example, writing a PDF document,
but those results cannot
flow through the pipeline. Similarly, one can imagine a component that
takes no inputs, reads a non-XML file from a URI, and produces an XML
output. But the non-XML file cannot be an input to the
component or pipeline.</para>

<para>Each input and output is declared to accept or produce either a single
document or a sequence of documents. It is not a static error to connect a port
which produces a sequence of documents to a port that accepts only a single
document. It is, however, a dynamic error if the former component actually
produces more than a single document at run time.</para>

<para>Components may also produce error, warning, and informative
messages. These messages appear on a special “error output” that is available
in the catch clause of a <link linkend="c.try">try/catch</link>.</para>

</section>

<section xml:id="parameters">
<title>Parameters</title>

<para><termdef xml:id="dt-parameter">A <glossterm>parameter</glossterm> is
a QName/value pair.</termdef> The value of a parameter must be a string.
If a document, node, or other value is given, its (XPath 1.0) string value
is computed and that string is used.
</para>
</section>

<section xml:id="flow-graph">
<title>Flow Graph</title>

<para><termdef xml:id="dt-flow-graph">The components of a pipeline are
the nodes of a <glossterm>flow graph</glossterm>. The inputs and
outputs of the components are connected by arcs in that
graph.</termdef></para>

<para>Consider two components in such a graph, “component A” and
“component B”.</para>

<para><termdef xml:id="dt-connected">Components A and B are
<glossterm>connected</glossterm> if they are either
directly or indirectly connected.  Component A is directly
connected to B if an output of A is associated with an input
port of B.  Component A is indirectly connected to B if there
is a chain of directly connected components that allows
traversal from A to B.</termdef></para>

<para>With respect to <glossterm>connected</glossterm> components, we can speak of
one component being either before or after another.
<termdef xml:id="dt-before">Component A is <glossterm>before</glossterm>
component B if component B
is one of the <glossterm>contained steps</glossterm> of component A, either directly or indirectly, or if any output
from component A is connected to any input of component B, either
directly or indirectly.</termdef>
<termdef xml:id="dt-after"><glossterm>after</glossterm> is the converse
of <glossterm>before</glossterm>.</termdef></para>

<para>It is <glossterm>static error</glossterm> if a component is either before
or after itself. In other words, the <glossterm>flow graph</glossterm> must
be acyclic.</para>
</section>
</section>

<section xml:id="langconstructs">
<title>Language Constructs</title>

<para>This section describes the core language constructs of XProc.
</para>

<section xml:id="c.pipeline">
<title>Pipeline</title>

<para>A [[pipeline]] component encapsulates the behavior of a set of
components. It has a number of declared input and output ports and
parameters. Viewed from the outside, it is a black box which performs
some calculation on the inputs and produces the outputs. From the
pipeline author's perspective, the computation performed by the
pipeline is described in terms of a set of <glossterm>contained
steps</glossterm> which reads the pipeline's inputs and produce the
pipeline's outputs.</para>

<para>For example, a pipeline might accept a document and a stylesheet
as input; perform XInclude, validation, and transformation over its
inputs; and produce a sequence of formatted documents as its
output.</para>
</section>

<section xml:id="c.for-each">
<title>For-Each</title>

<para>A [[for-each]] component processes a sequence of documents,
applying a <glossterm>subpipeline</glossterm> to each document in
turn. In cases where a subpipeline requires a single document input,
but a pipeline needs to process a sequence of documents with that
subpipeline, the [[for-each]] construct can be used.</para>

<para>The result of the [[for-each]] is a sequence of the documents
produced by processing each individual document in the input sequence.
If the subpipeline is connected to one or more output ports on
the [[for-each]], what appears on each of those ports is the sequence
of documents produced by each iteration of the loop.</para>

<para>For example, a [[for-each]] might accept a sequence of DocBook
chapters as its input, process each chapter in turn with XSLT, and
produce a sequence of formatted chapters as its output.</para>
</section>

<section xml:id="c.viewport">
<title>Viewport</title>

<para>A [[viewport]] component processes a single document, applying
a <glossterm>subpipeline</glossterm> to one or more subsections of the document. The
result of the [[viewport]] is a copy of the original document with the
selected subsections replaced by the results of applying the
subpipeline
to them.</para>

<para>For example, a [[viewport]] might accept an XHTML document as its
input, apply encryption to selected <tag>div</tag> elements within
that document, and return an XHTML document that is the same as the
original except that each selected <tag>div</tag> has been replaced by
its encrypted result.</para>
</section>

<section xml:id="c.choose">
<title>Choose</title>

<para>A [[choose]] component selects exactly one of a list of possible
<glossterm baseform="subpipeline">subpipelines</glossterm> based on the evaluation of XPath
expressions.</para>

<para>Each subpipeline is effectively guarded by an XPath expression.
The [[choose]] considers each subpipeline in turn and selects the first (and
only the first) subpipeline for which the guard expression evaluates
to true. The last subpipeline may be designated the default subpipeline;
it will be selected if no preceding subpipeline was selected.</para>

<para>After a <glossterm>subpipeline</glossterm> is selected, it is
evaluated as if only it had been present. The result of the [[choose]]
is the result of the selected <glossterm>subpipeline</glossterm>.</para>

<para>For example, a [[choose]] might test a schema and apply XML
Schema validation to an input document if the schema is an XML Schema
document, apply RELAX NG validation if the schema is a RELAX NG
grammar, or perform no validation otherwise.</para>

<para>In order to ensure that the result of the [[choose]] is
consistent irrespective of the subpipeline chosen, each subpipeline must
declare the same number of outputs with the same names. It is a 
<glossterm>static error</glossterm> if two subpipelines in a [[choose]]
declare different outputs.</para>

<para>It is a <glossterm>dynamic error</glossterm> if no subpipeline
is selected by the [[choose]] and no default is provided.</para>
</section>

<section xml:id="c.group">
<title>Group</title>

<para>A [[group]] component encapsulates the behavior of a set of
components. It is a convenience wrapper for a collection of components
and may be used to perform parameter renaming to aid in reuse of sets
of components.</para>
</section>

<section xml:id="c.try">
<title>Try/Catch</title>

<para>A [[try]] component isolates a <glossterm>subpipeline</glossterm>, preventing any
errors that arise within it from being exposed to the rest of the
pipeline. A [[try]] component begins with two subpipelines: an initial
[[group]] and a [[catch]]. It
evaluates the initial subpipeline and, if no errors occur, the results of that
pipeline are the results of the component. However, if any errors
occur, it abandons the first subpipeline, discarding any output that
it may have generated, and evaluates the [[catch]] subpipeline. In this
case, the results of the [[catch]] subpipeline are the results of the
[[try]] component.</para>

<para>For example, a pipeline might attempt to process a document by
dispatching it to some web service. If the web service succeeds, then
those results are passed to the rest of the pipeline. However, if the
web service cannot be contacted or reports an error, the [[catch]]
component can provide some sort of default for the rest of the
pipeline.</para>

<para>In order to ensure that the result of the [[try]] is consistent
irrespective of whether the [[try]] subpipeline provides its output or
the [[catch]] subpipeline does, both the [[try]] and [[catch]]
subpipeline must declare the same number of outputs with the same
names. It is a <glossterm>static error</glossterm> if the two
subpipelines declare different outputs.</para>

<para>In order to support corrective action in the [[catch]]
subpipeline, components inside the [[catch]] have access to all the
error output of the components that were in the [[try]]
subpipeline on a special port named “<literal>#error</literal>”.</para>

<note>
<para>In evaluating the [[try]] subpipeline, failure of one component
may cause other components to fail. In addition, some components that
fail may not produce output on their error ports and some components
that succeeded may produce such output. This pipeline language places
no constraints on the order of error messages provided to the
[[catch]] subpipeline, nor does it attempt to guarantee that such
output will be available in all cases.</para>
</note>

<para>The error documents that appear <rfc2119>should</rfc2119> conform to 
<xref linkend="err-vocab"/>.
</para>
</section>

<section xml:id="c.declarecomponent">
<title>Other Components</title>

<para>A pipeline document may declare additional components. These may
be implementation-defined components or may be defined through some
implementation-dependent extension mechanism. Each declared component
must have a name and a <glossterm>signature</glossterm>. It is a <glossterm>static
error</glossterm> if a pipeline refers to a component that is not
recognized by the processor.</para>
</section>
</section>

<section xml:id="syntax">
<title>Syntax</title>

<para>This section describes the syntactic elements necessary to
instantiate a pipeline.
</para>

<section xml:id="syntax-overview">
<title>Overview</title>

<para>At the highest level, a pipeline is a collection of steps. Each
step has a unique name and instantiates a particular component. The
component has a <glossterm>signature</glossterm> and that signature has to be satisified by
the inputs and parameters specified on the step. Recall that a
pipeline is not required to consume all the outputs of a component,
but it must identify all the inputs and required parameters.</para>

<para>Components that contain <glossterm>subpipeline</glossterm>s are represented naturally
using XML hierarchy by placing steps inside other steps.</para>

<section xml:id="syntax-docs-ports">
<title>Associating Documents with Ports</title>

<para>A step can bind a document or a sequence of documents to a port
in three ways: by source, by URI, or by providing it “here”, as the content of
the element establishing the binding. A document must be specified in
exactly one of these ways.</para>

<variablelist>
<varlistentry>
<term>Specified by URI</term>
<listitem>
<para><termdef xml:id="dt-input-uri">A document is specified
<glossterm>by URI</glossterm>
if it refers to it with a URI.</termdef> The
<tag class="attribute">href</tag> attribute is used for this purpose.</para>

<para>In this example, the input to the Identity step named
“<literal>otherstep</literal>” comes from “<uri>http://example.com/input.xml</uri>”.
</para>

<programlisting><![CDATA[<p:step name="otherstep" component="p:identity">
  <p:input port="document" href="http://example.com/input.xml"/>
</p:step>]]></programlisting>

<para>It is a <glossterm>dynamic error</glossterm> if the processor
attempts to retrieve the specified URI and fails. (For example, if the
resource does not exist or is not accessible with the users
authentication credentials.)</para>
</listitem>
</varlistentry>

<varlistentry>
<term>Specified by source</term>
<listitem>
<para><termdef xml:id="dt-input-source">A document is specified
<glossterm>by source</glossterm>
if it refers to a specific port on another step.</termdef> The
<tag class="attribute">step</tag> and
<tag class="attribute">source</tag> attributes are used for this purpose.
The specified port must either be a declared input on some ancestor (e.g.,
an enclosing <tag>p:choose</tag> or <tag>p:for-each</tag>) or it
must be an output port of some other step.
In some contexts there are additional constraints on the step that can
be selected, for example, that it must be (or must not be) a
descendant of the step on which the binding occurs.</para>

<para>In this example, the input to the XInclude step named
“<literal>expand</literal>” comes from the “<literal>result</literal>”
port of the step named “<literal>otherstep</literal>”.</para>

<programlisting><![CDATA[<p:step name="expand" component="p:xinclude">
  <p:input port="document" step="otherstep" source="result"/>
</p:step>]]></programlisting>

<!--
<para><termdef xml:id="dt-source">A source specification identifies a 
<glossterm>source</glossterm> if the specified port is either a declared input
on some ancestor or an output of some other step.</termdef>
<termdef xml:id="dt-sink">A source specification identifies a 
<glossterm>sink</glossterm> if the specified port is a declared output
on some ancestor or an input of some other step.</termdef></para>
-->

<para>It is a <glossterm>static error</glossterm> if the specified port
does not exist.</para>
</listitem>
</varlistentry>

<varlistentry>
<term>Specified by here document</term>
<listitem>
<para><termdef xml:id="dt-input-here">An document is specified by
<glossterm>here document</glossterm>
if it is contained in the body of the element that binds it.</termdef></para>

<para>In this example, the stylesheet input to the XSLT step named
“<literal>xform</literal>” comes from the content of the input element.</para>

<programlisting><![CDATA[<p:step name="xform" component="p:xslt">
  <p:input port="document" source="expand!result"/>
  <p:input port="stylesheet">
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    version="1.0">
      ...
    </xsl:stylesheet>
  </p:input>
</p:step>]]></programlisting>

<para>Here documents are considered “quoted”, they are not
interpolated or available to the pipeline processor in any way except
as a document flowing through the pipeline.</para>
</listitem>
</varlistentry>
</variablelist>
</section>

<section xml:id="scoping">
<title>Scoping of Names</title>

<para>The scope of a port name is the component on which it is defined. The names
of all input and output ports on any component must be unique.</para>

<para>The scope of step names is the <glossterm>flow graph</glossterm>.</para>

<note role="editorial" xml:id="component-names">
<para>Should we say that components have names and remove steps from the
equation all together?</para>
</note>
</section>

<section xml:id="syntax-shortcuts">
<title>Syntactic Shortcuts</title>

<para>In order for step container components (such as
<tag>p:for-each</tag> and <tag>p:choose</tag>) to function as
“black boxes” the way other components do, it is necessary to make sure
that they are wholly self-contained. This means that any inputs, outputs, and
parameters that are used within the subpipeline must be declared:</para>

<programlisting><![CDATA[<p:pipeline xmlns:p="http://www.w3.org/2006/08/pipeline">
<p:declare-input port="document"/>
<p:declare-parameter name="makeHTML" required="yes"/>

<!-- for the sake of convenience, we assume these steps take no
     inputs and produce a single output on a port named "result" -->
<p:step name="gen-fo" component="ex:generate-fo-stylesheet"/>
<p:step name="gen-html" component="ex:generate-html-stylesheet"/>

<p:choose name="choose-result">
  <p:declare-input port="document" source="!document"/>
  <p:declare-input port="fo-style" source="gen-fo!result"/>
  <p:declare-input port="html-style" source="gen-html!result"/>
  <p:declare-parameter name="makeHTML" select="$makeHTML"/>

  <p:when test="$makeHTML = '1'">
    <p:step name="makeHTML" component="p:xslt">
      <p:input port="document" source="chose-result!document"/>
      <p:input port="stylesheet" source="choose-result!html-style"/>
    </p:step>
    <p:step name="writeHTML" component="p:serialize">
      <p:input port="document" source="makeHTML!result"/>
    </p:step>
  </p:when>

  <p:otherwise>
    <p:step name="makeFO" component="p:xslt">
      <p:input port="document" source="chose-result!document"/>
      <p:input port="stylesheet" source="choose-result!fo-style"/>
    </p:step>
    <p:step name="writePDF" component="p:fo-to-pdf">
      <p:input port="document" source="makeFO!result"/>
    </p:step>
  </p:otherwise>
</p:choose>

</p:pipeline>]]></programlisting>

<para>However, in practice, forcing authors to declare all of the inputs
and parameters to each component is tedious and error-prone. What's more,
the pipeline processor can actually determine what additional declarations
are necessary simply by examining the source declarations on the steps
contained within the step.</para>

<para>Therefore, we allow the syntactic shortcut of simply referring to
in-scope sources and parameters directly.</para>

<programlisting><![CDATA[<p:pipeline xmlns:p="http://www.w3.org/2006/08/pipeline">
<p:declare-input port="document"/>
<p:declare-parameter name="makeHTML" required="yes"/>

<!-- for the sake of convenience, we assume these steps take no
     inputs and produce a single output on a port named "result" -->
<p:step name="gen-fo" component="ex:generate-fo-stylesheet"/>
<p:step name="gen-html" component="ex:generate-html-stylesheet"/>

<p:choose name="choose-result">
  <p:when test="$makeHTML = '1'">
    <p:step name="makeHTML" component="p:xslt">
      <p:input port="document" source="!document"/>
      <p:input port="stylesheet" source="gen-html!result"/>
    </p:step>
    <p:step name="writeHTML" component="p:serialize">
      <p:input port="document" source="makeHTML!result"/>
    </p:step>
  </p:when>

  <p:otherwise>
    <p:step name="makeFO" component="p:xslt">
      <p:input port="document" source="!document"/>
      <p:input port="stylesheet" source="gen-fo!result"/>
    </p:step>
    <p:step name="writePDF" component="p:fo-to-pdf">
      <p:input port="document" source="makeFO!result"/>
    </p:step>
  </p:otherwise>
</p:choose>

</p:pipeline>]]></programlisting>

<para>These shortcuts are purely syntactic. The processor is required to
behave as if appropriate, unique declarations with the corresponding remapping
of names had been present.</para>

<note role="editorial" xml:id="allow-decl-input">
<para>The WG is still considering whether or not authors will be allowed to
write pipelines using the fully-qualified syntax. This draft does not actually
allow <tag class="element">p:declare-input</tag> on language constructs so the
fully qualified example given above is not syntactically valid.</para>
</note>

</section>

<section xml:id="extension-attributes">
<title>Extension attributes</title>

<para><termdef xml:id="dt-extension-attribute">An element from the XProc
namespace may have any attribute not from the XProc namespace, provided that the
expanded-QName of the attribute has a non-null namespace URI. These attributes are
called <glossterm>extension attributes</glossterm>.</termdef>
The presence of an extension attribute must not cause the flow graph to
differ from the flow graph that any other conformant XProc processor
might produce. They must not cause the processor to fail to signal an error that a
conformant processor is required to signal. This means that an
extension attribute must not change the effect of any XProc element
except to the extent that the effect is
implementation-defined or implementation-dependent.</para>

<para>A processor which encounters an extension attribute that it does not
recognize <rfc2119>must</rfc2119> behave as if the attribute was not present.</para>

</section>

<section xml:id="extension-elements">
<title>Extension elements</title>

<para><termdef xml:id="dt-extension-element">Outside the context of a 
<quote>here document</quote>, any element
not in the XProc namespace is an <glossterm>extension element</glossterm>.</termdef>
The presence of an extension element must not cause the flow graph to
differ from the flow graph that any other conformant XProc processor
might produce. They must not cause the processor to fail to signal an error that a
conformant processor is required to signal. This means that an
extension element must not change the effect of any XProc element
except to the extent that the effect is
implementation-defined or implementation-dependent.</para>

<para>Inside the context of a 
<glossterm linkend="dt-input-here">here document</glossterm>, all content is
considered quoted so neither extension elements nor XProc elements are said to
occur.</para>

<para>A processor which encounters an extension element that it does not
recognize <rfc2119>must</rfc2119> behave as if neither the element nor its
attributes, nor any of its content was present.</para>
</section>
</section>

<section xml:id="vocabulary">
<title>Pipeline Vocabulary</title>

<para>This section describes the XML vocabulary that instantiates a pipeline.</para>

<!-- ============================================================ -->

<section xml:id="p.pipeline">
<title>p:pipeline Element</title>

<para>A <tag>p:pipeline</tag> represents a [[pipeline]]. Its children declare
the inputs, outputs, and parameters that the pipeline exposes and
the <glossterm>subpipeline</glossterm> that constitutes its definition.</para>

<e:element-syntax name="pipeline">
  <e:in-category name="language-construct"/>
  <e:attribute name="name">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:sequence>
    <e:element name="declare-input" repeat="zero-or-more"/>
    <e:element name="declare-output" repeat="zero-or-more"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
    <e:element name="import" repeat="zero-or-more"/>
    <e:element name="declare-component" repeat="zero-or-more"/>
    <e:model name="subpipeline"/>
  </e:sequence>
</e:element-syntax>

<para>If specified, the <tag class="attribute">name</tag> must be
unique across all available pipelines. If a <tag>p:pipeline</tag>
occurs as the child of a <tag>p:pipeline-library</tag> element, it must
be named.</para>

<example xml:id="ex.p.pipeline">
<title>A Sample Pipeline Document</title>
<programlisting><![CDATA[<p:pipeline name="buildspec">
  <p:declare-input port="document"/>
  <p:declare-input port="stylesheet"/>
  <p:declare-output port="result"/>
  <p:declare-parameter name="validate"/>
  …
</p:pipeline>]]></programlisting>
</example>

</section>

<!-- ============================================================ -->

<section xml:id="p.declare-input">
<title>p:declare-input Element</title>

<para>A <tag>p:declare-input</tag> declares an input port.</para>

<e:element-syntax name="declare-input">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>The <tag class="attribute">port</tag> attribute defines the name
of the port. It is a <glossterm>static error</glossterm> two define
two ports with the same name.</para>

<para>An input declaration can indicate if a sequence of documents is
allowed to appear on the declared port. If
<tag class="attribute">sequence</tag> is specified with the value “yes”,
then a sequence is allowed. If the
<tag class="attribute">sequence</tag> is not specified, or has the value
“no”, then it is a <glossterm>dynamic error</glossterm> for a sequence
of more than one document to appear on the declared port.</para>

<para>The declaration <rfc2119>may</rfc2119> be accompanied by a
binding (or default binding) for the input. This binding can be
accomplished
<glossterm linkend="dt-input-source">by source</glossterm>:</para>

<e:element-syntax name="declare-input">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="step" required="yes">
    <e:data-type name="step name"/>
  </e:attribute>
  <e:attribute name="source" required="yes">
    <e:data-type name="port name"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para><glossterm linkend="dt-input-uri">by URI</glossterm>:</para>

<e:element-syntax name="declare-input">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="href" required="yes">
    <e:data-type name="URI"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>or by
<glossterm linkend="dt-input-here">here document</glossterm>:</para>

<e:element-syntax name="declare-input">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:model name="heredocument"/>
</e:element-syntax>

<para>If a 
<glossterm linkend="dt-input-source">by source</glossterm> binding is
used, the port selected must be an output port on a step which is not a
descendant of
the step on which the <tag>p:declare-input</tag> appears or it must be
a port declared with <tag>p:declare-input</tag> on some ancestor (e.g.,
an enclosing <tag>p:choose</tag> or <tag>p:for-each</tag>) of the
step.</para>

<para>If a binding is provided, a <tag class="attribute">select</tag> expression
<rfc2119>may</rfc2119> also be provided.
If provided, the
specified XPath select expression is used to filter the document(s) that are read.
Each matching node or set of nodes is wrapped in a document and
provided to the input port. See <xref linkend="p.input"/>.</para>
</section>

<!-- ============================================================ -->

<section xml:id="p.declare-parameter">
<title>p:declare-parameter Element</title>

<para>A <tag>p:declare-parameter</tag> declares a parameter.</para>

<e:element-syntax name="declare-parameter">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="token"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>Components must declare the parameters that they accept.</para>

<para>The <tag class="attribute">name</tag> attribute must be a single
asterisk (<literal>*</literal>), a QName, or a string of the form
<literal>*:<replaceable>NCName</replaceable></literal> or
<literal><replaceable>NCName</replaceable>:*</literal>.</para>

<para>If <tag class="attribute">name</tag> is a QName, then the declaration
may include a default value using either content or a
<tag class="attribute">select</tag> attribute as per
<tag>p:param</tag>.</para> 
</section>

<!-- ============================================================ -->

<section xml:id="p.declare-output">
<title>p:declare-output Element</title>

<para>A <tag>p:declare-output</tag> identifies an output port.</para>

<e:element-syntax name="declare-output">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>The <tag class="attribute">port</tag> attribute defines the name
of the port. It is a <glossterm>static error</glossterm> to declare two
ports with the same name.</para>

<para>An output declaration can indicate if a sequence of documents is
allowed to appear on the declared port. If
<tag class="attribute">sequence</tag> is specified with the value “yes”,
then a sequence is allowed. If the
<tag class="attribute">sequence</tag> is not specified, or has the value
“no”, then it is a <glossterm>dynamic error</glossterm> if the component
produces a sequence of more than one document on the declared port.</para>

<para>On a step container, the declaration <rfc2119>must</rfc2119> be accompanied by a
binding for the output. This binding can be accomplished
<glossterm linkend="dt-input-source">by source</glossterm>:</para>

<e:element-syntax name="declare-output">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="step" required="yes">
    <e:data-type name="step name"/>
  </e:attribute>
  <e:attribute name="source" required="yes">
    <e:data-type name="port name"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para><glossterm linkend="dt-input-uri">by URI</glossterm>:</para>

<e:element-syntax name="declare-output">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="href" required="yes">
    <e:data-type name="URI"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>or by
<glossterm linkend="dt-input-here">here document</glossterm>:</para>

<e:element-syntax name="declare-output">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="sequence">
    <e:data-type name="yes|no"/>
  </e:attribute>
  <e:model name="heredocument"/>
</e:element-syntax>

<para>If a 
<glossterm linkend="dt-input-source">by source</glossterm> binding is
used, the port selected must be an output port on an step which is a descendant
of the step on which the <tag>p:declare-output</tag> appears.
</para>
</section>

<!-- ============================================================ -->

<section xml:id="p.step">
<title>p.step Element</title>

<para>A <tag>p:step</tag> represents a component in a pipeline.</para>

<e:element-syntax name="step">
  <e:in-category name="language-construct"/>
  <e:attribute name="component" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="name" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:sequence>
    <e:element name="input" repeat="zero-or-more"/>
    <e:element name="import-param" repeat="zero-or-more"/>
    <e:element name="parameter" repeat="zero-or-more"/>
  </e:sequence>
</e:element-syntax>

<para>The <tag class="attribute">component</tag> attribute identifies the
component to be instantiated. It is a <glossterm>static error</glossterm> if
the <tag class="attribute">name</tag> is not unique in the current scope, if the
specified <tag class="attribute">component</tag>
is not known to the processor, or if the specified
inputs, outputs, and parameters do not
<glossterm baseform="matches">match</glossterm> the component's
<glossterm>signature</glossterm>.</para> 
</section>

<!-- ============================================================ -->

<section xml:id="p.input">
<title>p.input Element</title>

<para>A <tag>p:input</tag> identifies input for a component.</para>

<para>Inputs identify their source in exactly one of three ways,
<glossterm linkend="dt-input-source">by source</glossterm>:
</para>

<e:element-syntax name="input">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:attribute name="step" required="yes">
    <e:data-type name="step name"/>
  </e:attribute>
  <e:attribute name="source" required="yes">
    <e:data-type name="port name"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para><glossterm baseform="by URI">by URI:</glossterm>
</para>

<e:element-syntax name="input">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:attribute name="href" required="yes">
    <e:data-type name="URI"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>or by
<glossterm linkend="dt-input-here">here document</glossterm>:
</para>

<e:element-syntax name="input">
  <e:in-category name="language-construct"/>
  <e:attribute name="port" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:model name="heredocument"/>
</e:element-syntax>

<para>It is a <glossterm>static error</glossterm> if more than one of
<tag class="attribute">source</tag>,
<tag class="attribute">uri</tag> or here document is
specified.</para>

<para>The <tag class="attribute">port</tag> attribute identifies the
input port of the component that will read from the specified source.
It is a
<glossterm>static error</glossterm>
if the name given does not match the name of an input port for the
component or if  more than one input is specified
for any given port.</para>

<para>The <tag class="attribute">select</tag> expression, if specified,
applies the specified XPath select expression to the document(s) that are
read. Each matching node or set of nodes is wrapped in a document and provided
to the input port. In other words,</para>

<programlisting><![CDATA[<p:input port="document" href="http://example.org/input.html"/>]]></programlisting>

<para>provides a single document, but</para>

<programlisting><![CDATA[<p:input port="document" href="http://example.org/input.html" select="//html:div"/>]]></programlisting>

<para>provides a sequence of zero or more documents, one for each matching
<code>html:div</code> in <uri>http://example.org/input.html</uri>.</para>

<programlisting><![CDATA[<p:input port="document" source="stepname!portname" select="//html:div"/>]]></programlisting>

<para>provides a sequence of zero or more documents, one for each matching
<code>html:div</code> in the document (or each of the documents)
that is read from the <literal>portname</literal>
port of the step named <literal>stepname</literal>.</para>

</section>

<!-- ============================================================ -->

<section xml:id="p.param">
<title>p:param Element</title>

<para>A <tag>p:param</tag> associates a particular value with a parameter.</para>

<para>The value of the parameter can be specified in several ways; as the
content of
the <tag>p:param</tag> element:</para>

<e:element-syntax name="param">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:model name="any content"/>
</e:element-syntax>

<para>In this case, the (XPath 1.0) <emphasis>string value</emphasis> of the
content becomes the value of the parameter.</para>

<para>With a <tag class="attribute">value</tag> attribute:</para>

<e:element-syntax name="param">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="value" required="yes">
    <e:data-type name="string"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>Or as an XPath expression. In this case, the context in which
the expression is evaulated must be specified in exactly one of three
ways, <glossterm linkend="dt-input-source">by source</glossterm>:
</para>

<e:element-syntax name="param">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="Qname"/>
  </e:attribute>
  <e:attribute name="step" required="yes">
    <e:data-type name="step name"/>
  </e:attribute>
  <e:attribute name="source" required="yes">
    <e:data-type name="port name"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para><glossterm baseform="by URI">by URI:</glossterm>
</para>

<e:element-syntax name="param">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:attribute name="href" required="yes">
    <e:data-type name="URI"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>or by
<glossterm linkend="dt-input-here">here document</glossterm>:
</para>

<e:element-syntax name="param">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="QNName"/>
  </e:attribute>
  <e:attribute name="select">
    <e:data-type name="xpath expression"/>
  </e:attribute>
  <e:model name="heredocument"/>
</e:element-syntax>

<para>The (XPath 1.0) <emphasis>string value</emphasis> of the result of evaluating
the expression becomes the value of the parameter.</para>

</section>

<!-- ============================================================ -->

<section xml:id="p.import-param">
<title>p:import-param Element</title>

<para>An <tag>p:import-param</tag> provides a set of in-scope parameters
to a component.</para>

<e:element-syntax name="import-param">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="token"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>All in-scope parameters which match the <tag class="attribute">name</tag>
are made available to the component as if they had been specified with
individual <tag>p:param</tag> elements.</para>

<para>The <tag class="attribute">name</tag> attribute must be a single
asterisk (<literal>*</literal>), a QName, or a string of the form
<literal>*:<replaceable>NCName</replaceable></literal> or
<literal><replaceable>NCName</replaceable>:*</literal>.</para>
</section>

<!-- ============================================================ -->

<section xml:id="p.for-each">
<title>p:for-each Element</title>

<para>A <tag>p:for-each</tag> represents a [[for-each]].</para>

<e:element-syntax name="for-each">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:sequence>
    <e:element name="declare-input"/>
    <e:element name="declare-output" repeat="zero-or-more"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
    <e:model name="subpipeline"/>
  </e:sequence>
</e:element-syntax>

<para>Exactly one input must be declared and it must include a binding
for the port it declares. If outputs are declared, they must also include a binding.
The processor will provide each document
read through that binding to the <glossterm>subpipeline</glossterm> that the
<tag>p:for-each</tag> contains, one at a time.
For each declared output, the processor will collect all the
documents that are produced for that output from all the
iterations, in order, into a sequence.
The result of the <tag>p:for-each</tag>
is that set of document sequences.</para>

<para><xref linkend="ex.p.for-each"/> shows an example of a <tag>p:for-each</tag>
in action.</para>

<example xml:id="ex.p.for-each">
<title>A Sample For-Each</title>
<programlisting><![CDATA[<p:for-each name="chapters">
  <p:declare-input port="chap" href="http://example.org/docbook.xml" select="//chapter"/>
  <p:declare-output port="html" source="xform-to-html!result"/>
  <p:declare-output port="fo" source="xform-to-fo!result"/>
  <p:step name="xform-to-fo" component="p:xslt">
    <p:input name="document" source="chapters!chap"/>
    <p:input name="stylesheet" href="fo/docbook.xsl"/>
  </:step>
  <p:step name="xform-to-html" component="p:xslt">
    <p:input name="document" source="chapters!chap"/>
    <p:input name="stylesheet" href="html/docbook.xsl"/>
  </:step>
</p:for-each>]]></programlisting>
</example>

<para>The <code>//chapter</code>s of the DocBook document are
selected. Each chapter is transformed into HTML and XSL FO using an
XSLT step. The resulting HTML and FO documents are aggregated together
and appear on the <literal>html</literal> and <literal>fo</literal>
ports, respectively, of the <literal>chapters</literal> step.</para>

<para>It is a <glossterm>static error</glossterm> if there is not exactly one
<tag>p:declare-input</tag> child of <tag>p:for-each</tag>, if the declared
input does not specify a binding, or if it specifies a binding to a step inside
the <tag>p:for-each</tag>.</para>

<para>It is a <glossterm>static error</glossterm> if any declared output
does not specify a binding.</para>
</section>

<section xml:id="p.viewport">
<title>p:viewport Element</title>

<para>A <tag>p:viewport</tag> represents a [[viewport]].</para>

<e:element-syntax name="viewport">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:sequence>
    <e:element name="declare-input"/>
    <e:element name="declare-output"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
    <e:model name="subpipeline"/>
  </e:sequence>
</e:element-syntax>

<para>Exactly one input must be declared and it must include both a
binding and a <tag class="attribute">select</tag> expression. Exactly
one output must be declared and it must include a binding. The
processor will provide a document that contains each set of nodes that
matches the specified select expression through the input binding to
the <glossterm>subpipeline</glossterm> that the <tag>p:viewport</tag> contains, one at a
time. What appears on the output from the <tag>p:viewport</tag> will
be a copy of the input document except that where each matching node
or set of nodes appears, the result of applying the subpipeline to
those nodes will be output.</para>

<para>It is a <glossterm>dynamic error</glossterm> if the input source is
a sequence of more than one document or if the output from any iteration
is a sequence of more than one document.</para>

<para><xref linkend="ex.p.for-each"/> shows an example of a <tag>p:for-each</tag>
in action.</para>

<example xml:id="ex.p.viewport">
<title>A Sample Viewport</title>
<programlisting><![CDATA[<p:viewport name="encdivs">
  <p:declare-input port="div" source="step!port" select="//h:div[@class='enc']"/>
  <p:declare-output port="html" source="encrypt!result"/>
  <p:step name="encrypt" component="p:encrypt-document">
    <p:input name="document" source="encdivs!div"/>
  </:step>
</p:viewport>]]></programlisting>
</example>

<para>The <code>//h:div[@class='enc']</code>s of the document are
selected. Each selected <code>div</code> is encrypted and the resulting
encrypted version replaces the original div. The result of the step is
a copy of the input document with each selected <code>div</code> encrypted.</para>

<para>It is a <glossterm>static error</glossterm> if there is not exactly one
<tag>p:declare-input</tag> child and exactly one
<tag>p:declare-output</tag> child of <tag>p:viewport</tag>, if the declared
ports do not specify a binding, or if the input port specifies a binding to a step inside
the <tag>p:viewport</tag>.</para>
</section>

<section xml:id="p.choose">
<title>p:choose/p:when/p:otherwise Elements</title>

<para>A <tag>p:choose</tag> represents a [[choose]].</para>

<e:element-syntax name="choose">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:attribute name="source">
    <e:data-type name="source specification"/>
  </e:attribute>
  <e:sequence>
    <e:element name="when" repeat="zero-or-more"/>
    <e:element name="otherwise" repeat="zero-or-one"/>
  </e:sequence>
</e:element-syntax>

<para>Where <tag>p:when</tag> specifies a conditional branch.</para>

<e:element-syntax name="when">
  <e:in-category name="language-construct"/>
  <e:attribute name="test" required="yes">
    <e:data-type name="expression"/>
  </e:attribute>
  <e:attribute name="source">
    <e:data-type name="source specification"/>
  </e:attribute>
  <e:sequence>
    <e:element name="declare-output" repeat="zero-or-more"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
    <e:model name="subpipeline"/>
  </e:sequence>
</e:element-syntax>

<para>And <tag>p:otherwise</tag> specifies the default branch.</para>

<e:element-syntax name="otherwise">
  <e:in-category name="language-construct"/>
  <e:sequence>
    <e:element name="declare-output" repeat="zero-or-more"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
    <e:model name="subpipeline"/>
  </e:sequence>
</e:element-syntax>

<para>The <tag class="attribute">test</tag> expression is evaluated for each
<tag>p:when</tag> in turn. The first <tag>p:when</tag> for which the expression
evaluates to “true” is selected, all other <tag>p:when</tag> elements (and
the <tag>p:otherwise</tag>) are ignored. If no <tag>p:when</tag> has a test
expression which evaluates to “true”, then the <tag>p:otherwise</tag> is selected
and all <tag>p:when</tag> elements are ignored.</para>

<para>The context for each test expression is the document specified by the
<tag class="attribute">source</tag> attribute on the corresponding
<tag>p:when</tag>. If no 
<tag class="attribute">source</tag> attribute is specified on the <tag>p:when</tag>,
then the context is the document specified by the 
<tag class="attribute">source</tag> attribute on the <tag>p:choose</tag>.
It is a <glossterm>static error</glossterm> if no source is specified in either
place.</para>

<para>All of the <tag>p:when</tag> branches and the <tag>p:otherwise</tag>
must declare the same number of output ports with the same names. It is a 
<glossterm>static error</glossterm> if they do not.</para>

<para>The result of the <tag>p:choose</tag> is the result of the
selected branch. It is a <glossterm>dynamic error</glossterm> if no
<tag>p:when</tag> is selected and no <tag>p:otherwise</tag> is
specified.</para>
</section>

<section xml:id="p.group">
<title>p:group Element</title>

<para>A <tag>p:group</tag> is a wrapper for a <glossterm>subpipeline</glossterm>.</para>

<e:element-syntax name="group">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:sequence>
    <e:element name="declare-output" repeat="zero-or-more"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
    <e:model name="subpipeline"/>
  </e:sequence>
</e:element-syntax>

<para>The result of a <tag>p:group</tag> is its declared outputs.</para>
</section>

<section xml:id="p.try">
<title>p:try/p:catch Elements</title>

<para>A <tag>p:try</tag> represents a [[try/catch]].</para>

<e:element-syntax name="try">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="NCName"/>
  </e:attribute>
  <e:sequence>
    <e:element name="group"/>
    <e:element name="catch"/>
  </e:sequence>
</e:element-syntax>

<para>Where <tag>p:group</tag> is any pipeline group and <tag>p:catch</tag>
surrounds the error recovery behavior:</para>

<e:element-syntax name="catch">
  <e:in-category name="language-construct"/>
  <e:sequence>
    <e:element name="declare-output" repeat="zero-or-more"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
    <e:model name="subpipeline"/>
  </e:sequence>
</e:element-syntax>

<para>The <tag>p:try</tag> component evaluates the <tag>p:group</tag>. If the
group evaluates without signaling an error, that is the result of the
<tag>p:try</tag> component.</para>

<para>However, if any
component in that group signals an error, then the group is abandoned (any
accumulated output is discarded) and the <tag>p:catch</tag> <glossterm>subpipeline</glossterm> is
evaluated. In that case, the result of the <tag>p:catch</tag> is the result
of the <tag>p:try</tag> component.</para>

<para>If any component in the <tag>p:catch</tag> <glossterm>subpipeline</glossterm> signals an
error, the <tag>p:try</tag> fails.</para>

<para>Within the <tag>p:catch</tag> block, the special input port
<literal>!#error</literal> is defined. The document(s) on that port constitute
the error messages received from the component which failed. Note that the
order of the messages on that port is undefined. Note also that the failure
of one component may cause others to fail and the component which signaled
the error may not be the only or even the first component that failed.</para>

<para>Both the <tag>p:group</tag> and the <tag>p:catch</tag>
must declare the same number of output ports with the same names. It is a 
<glossterm>static error</glossterm> if they do not.</para>
</section>

<!-- ============================================================ -->

<section xml:id="p.declare-component">
<title>p:declare-component Element</title>

<para>A <tag>p:declare-component</tag> provides the name and <glossterm>signature</glossterm>
of an implementation-dependent component. It declares the inputs, outputs,
and parameters of the component.</para>

<e:element-syntax name="declare-component">
  <e:in-category name="language-construct"/>
  <e:attribute name="name" required="yes">
    <e:data-type name="QName"/>
  </e:attribute>
  <e:sequence>
    <e:element name="declare-input" repeat="zero-or-more"/>
    <e:element name="declare-output" repeat="zero-or-more"/>
    <e:element name="declare-parameter" repeat="zero-or-more"/>
  </e:sequence>
</e:element-syntax>

<note role="editorial" xml:id="external-binding">
<para>We need to make some provision for identifying an external binding,
even if it's implementation defined. We'll need some sort of mechanism
for declaring multiple implementations too.</para>
</note>

<para>It is a <glossterm>static error</glossterm> if a pipeline step
refers to a component that is not recognized by the processor. It is not
an error to declare such a component, only to use it.</para>

<para>Exactly one input declaration of a
<tag>p:declare-component</tag> <rfc2119>may</rfc2119> use the
<tag class="attribute">name</tag> “<literal>*</literal>” to indicate
that the component accepts an arbitrary number of inputs.
</para>

</section>

<!-- ============================================================ -->

<section xml:id="p.pipeline-library">
<title>p:pipeline-library Element</title>

<para>A <tag>p:pipeline-library</tag> contains one or more component
declarations and/or pipelines. It declares components that pipelines
can import.</para>

<e:element-syntax name="pipeline-library">
  <e:in-category name="language-construct"/>
  <e:sequence>
    <e:element name="import" repeat="zero-or-more"/>
    <e:element name="declare-component" repeat="zero-or-more"/>
    <e:element name="pipeline" repeat="zero-or-more"/>
  </e:sequence>
</e:element-syntax>

<example xml:id="ex.p.pipeline-library">
<title>A Sample Pipeline Library</title>
<programlisting><![CDATA[<p:pipeline-library>
  <p:declare-component name="extension-component">…</p:declare-component>
  <p:pipeline name="xinclude-and-validate">…</p:pipeline>
  <p:pipeline name="validate-and-transform">…</p:pipeline>
  …
</p:pipeline>]]></programlisting>
</example>

</section>

<!-- ============================================================ -->

<section xml:id="p.import">
<title>p:import Element</title>

<para>An <tag>p:import</tag> loads a pipeline or pipeline library, making
it available in the current context.</para>

<e:element-syntax name="import">
  <e:in-category name="language-construct"/>
  <e:attribute name="href" required="yes">
    <e:data-type name="URI"/>
  </e:attribute>
  <e:empty/>
</e:element-syntax>

<para>An import statement loads the specified URI and makes any pipelines
declared within it available to the current pipeline.</para>

<para>It is a <glossterm>dynamic error</glossterm> if the URI cannot
be retrieved or if, once retrieved, it does not point to a
<tag>p:pipeline-library</tag> or <tag>p:pipeline</tag>. If it points to
a <tag>p:pipeline</tag>, it is a <glossterm>dynamic error</glossterm> if the
pipeline does not have a <tag class="attribute">name</tag>.</para>
</section>
</section>
</section>

<section xml:id="errors">
<title>Errors</title>

<para>Errors in a pipeline can be divided into two classes:
<glossterm baseform="static error">static errors</glossterm>
and <glossterm baseform="dynamic error">dynamic errors</glossterm>.</para>

<section xml:id="static-errors">
<title>Static Errors</title>

<para><termdef xml:id="dt-static-error">A <glossterm>static
error</glossterm> is one which can be detected before pipeline evaluation
is even attempted.</termdef> Examples of static errors include cycles,
incorrect specification of inputs and outputs, and reference to unknown
components.</para>

<para>Static errors are fatal and must be detected before any components
are evaluated.</para>
</section>

<section xml:id="dynamic-errors">
<title>Dynamic Errors</title>

<para>A <termdef xml:id="dt-dynamic-error">A <glossterm>dynamic
error</glossterm> is one which occurs while a pipeline is being
evaluated.</termdef> Examples of dynamic errors include references
to URIs that cannot be resolved, components which fail, and pipelines
that exhaust the capacity of an implementation (such as memory or
disk space).</para>

<para>If a component fails due to a dynamic error, failure propogates
upwards until either a [[try]] is encountered or the entire pipeline
fails. In other words, outside of a [[try]], component failure causes
the entire pipeline to fail.</para>
</section>
</section>

<appendix xml:id="references">
<title>References</title>

<bibliolist>
<bibliomixed xml:id="xml-core-wg"><abbrev>XML Core Req</abbrev>
<citetitle xlink:href="http://www.w3.org/TR/proc-model-req/">XML
Processing Model Requirements</citetitle>
Dmitry Lenkov, Norman Walsh, editors. W3C
Working Group Note 05 April 2004
</bibliomixed>

<bibliomixed xml:id="xml-infoset-rec"><abbrev>Infoset</abbrev>
<citetitle xlink:href="http://www.w3.org/TR/xml-infoset/">XML
Information Set (Second Edition)</citetitle> John Cowan,
Richard Tobin, editors. W3C Working Group Note 04 February 2004.
</bibliomixed>

<bibliomixed xml:id="REC-xml"><abbrev>XML 1.0</abbrev>
<citetitle xlink:href="http://www.w3.org/TR/REC-xml/">Extensible
Markup Language (XML) 1.0 (Fourth Edition)</citetitle> Tim Bray,
Jean Paoli, C. M. Sperberg-McQueen, et. al.
editors. W3C Recommendation 16 August 2006.</bibliomixed>

<bibliomixed xml:id="xml11"><abbrev>XML 1.1</abbrev>
<citetitle xlink:href="http://www.w3.org/TR/xml11/">Extensible
Markup Language (XML) 1.1 (Second Edition)</citetitle> Tim Bray,
Jean Paoli, C. M. Sperberg-McQueen, et. al.
editors. W3C Recommendation 16 August 2006.</bibliomixed>

</bibliolist>
</appendix>

<xi:include href="glossary.xml"/>

<appendix xml:id="err-vocab">
<title>The Error Vocabulary</title>

<para>This appendix describes the XML vocabulary that components are
expected to use to identify messages on their error ports.</para>

<para>T.B.D.</para>
</appendix>

<appendix xml:id="std-components">
<title>Standard Component Library</title>

<para>This appendix describes the standard components that must be supported
by any conforming processor.</para>

<para>T.B.D.</para>

</appendix>

</specification>
