Declaring Input and Output Ports
Specifying port properties
Ports are the entry and exit points for data in your pipeline. When you declare a port in XProc, there are certain properties to control which data is accepted or produced by the port. An example of a port declaration is shown below:
<p:input port="source"
primary="true"
sequence="true"
content-type="xml html"/>
Ports have a name through which they are identified in the pipeline. You can set the port name by assigning the name
attribute. If your pipeline contains multiple inputs or outputs, you must specify the primary input or output port respectively by adding primary="true"
. A port expects one document by default. If you want a port to accept zero or more documents, you must set sequence="true"
. The content-type
attribute controls that only documents matching these MIME types are allowed to pass through that port. The port
attribute is required, the other attributes are optional.
Setting data sources
You can declare with these elements how a port connects to a data source:
p:empty
: the port is emptyp:document
: the port reads from or writes to an external resourcep:inline
: the document is declared inline in the source code of the pipelinep:pipe
: the port is connected to the input or output port of a step in the pipeline
As mentioned earlier, if you have multiple input and output ports, you must declare one of each as primary by adding primary="true"
. Ports expect typically one document. If you a port should accept zero to infinte documents, you need to add sequence="true"
.
The pipeline below inserts image
elements from the secondary input port into the doc
element passed to the primary input port. The ports named source
and result
are specified as primary ports.
The secondary input port images
accepts zero or more documents and is therefore marked with sequence="true"
. Ports with sequence="false"
or without sequence attribute only accept one document.
<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
version="3.0" name="my-pipeline">
<p:input port="source" primary="true">
<p:inline>
<doc/>
</p:inline>
</p:input>
<p:input port="images" sequence="true">
<p:inline>
<image src="image-1.png"/>
</p:inline>
<p:inline>
<image src="image-2.png"/>
</p:inline>
</p:input>
<p:output port="result"/>
<p:insert match="/doc" position="last-child">
<p:with-input port="insertion"
pipe="images@my-pipeline"/>
</p:insert>
</p:declare-step>
Output
<?xml version="1.0" encoding="UTF-8"?> <doc> <image src="image-1.png"/> <image src="image-2.png"/> </doc>
Implicit and explicit connections
Keeping the example above in mind, the primary input port of p:insert
is implicitly connected to the primary input port of the pipeline named source
. Secondary ports are not implicitly connected and therefore we need to specify an explicit connection from the step’s insertion
to the pipeline’s images
port.
We can express this explicit connection using the p:with-input
element. Ports can be referenced with the pipe
attribute in the form portname@stepname
. To reference external documents, you can use the href
attribute. When this connection is established, p:insert
inserts the data from the images
port into the document read from the source
port.
Since p:insert
is not followed by any other step, its output port result
is passed to the output port result
of the pipeline.