The logo is a pig framed between two angle brackets.

XProc 3.0 Tutorial

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 empty
  • p:document: the port reads from or writes to an external resource
  • p:inline: the document is declared inline in the source code of the pipeline
  • p: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.

Read more…