Define the step type exports of an XProc element, against the background of a set of URIs Visited of resources already visited, as follows:
type
of the elementhref
of the element. If
RU is a member of Visited, then an empty bag,
otherwise update Visited by adding RU to it, and
return the step type exports of the
document element of the retrieved representationThe changes to Visited mandated by the p:import case above are persistent, not scoped. That is, not only the recursive processing of the imported resource but also subsequent processing of siblings and ancestors must be against the background of the updated value. In practice this means either using a side-effected global variable, or not only passing Visited as an argument to any recursive or iterative processing, but also returning its updated value for subsequent use, along with the bag of step types.
Given a pipeline library document with actual resolved URI DU, it is an error (err:XS0036) if the step type exports of the document element of the retrieved representation, against the background of a singleton set containing DU, contains any duplicates.
Given a top-level pipeline document with actual resolved URI DU, it is an error (err:XS0036) if the bag-merger of the step type exports of the document element of the retrieved representation with the step type exports of its children, against the background of a singleton set containing DU, contains any duplicates.
Given a non-top-level p:pipeline
or
p:declare-step
element, it is an error (err:XS0036) if the bag-merger of the step type exports of its parent with the step type exports of its children, against the background of a copy of the Visited set of its parent, contains any duplicates.
The phrase "a copy of the Visited set" in the preceding
paragraph is meant to indicate that checking of non-top-level p:pipeline
or
p:declare-step
elements does not have a persistent
impact on the checking of its parent. The contrast is that whereas changes to
Visited pass both up and down through
p:import
, they pass only down through
p:pipeline and p:declare-step.
* The bag-merger of two or more bags (where a bag is an unordered lists or, equivalently, something like a set except that it may contain duplicates) is a bag constructed by starting with an empty bag and adding each member of each of the input bags in turn to it. It follows that the cardinality of the result is the sum of the cardinality of all the input bags.