XProc describes XML pipelines as XML: steps such as p:validate-with-relax-ng, p:xslt, p:delete and p:store connected by ports. XProc 1.0 was a W3C Recommendation (2010); 3.0 (12 September 2022) and 3.1 (30 May 2025) are Community Group Reports. XML Calabash 3.0.54 (codeberg.org/xmlcalabash/xmlcalabash3 (https://codeberg.org/xmlcalabash/xmlcalabash3 3,719 ), MIT) runs them on Saxon 726,956 . This pipeline validates the catalog, drops sold-out books and renders the FO of XSL-FO:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0" name="publish">
<p:input port="source"/>
<p:output port="result"/>
<p:validate-with-relax-ng>
<p:with-input port="schema" href="booknest.rng"/>
</p:validate-with-relax-ng>
<p:delete match="book[supply/availability = 'out-of-stock']"/>
<p:xslt><p:with-input port="stylesheet" href="pricelist.xsl"/></p:xslt>
<p:store href="instock.fo"/>
<p:identity>
<p:with-input select="count(//*:leader) || ' books in instock.fo'"/>
</p:identity>
</p:declare-step>cal=~/xml-tools/xmlcalabash-3.0.54/xmlcalabash.sh
$cal --input:source=booknest-catalog.xml publish.xpl; echo
sed 's/>39.50</>-39.50</' booknest-catalog.xml > bad.xml
$cal --input:source=bad.xml publish.xpl 2>&1 | grep -m 1 ErrorOutput
"5 books in instock.fo" Error: err:XC0155 at publish.xpl:4:29: RELAX NG validation failed.
The invalid feed stopped at the validation step (XC0155) and nothing was stored. Many teams express such chains in Airflow 129 or a Makefile instead (Orchestration and Pipelines).
XProc
XML Processing (XProc) is a language that describes a pipeline of operations to be performed on XML documents. Possible operations include file inclusion, validation, and XSLT transformations. Implementations include Calabash, Calumet, QuiXProc, and Tubular.The following pipeline includes another document with XInclude, validates the result against an XML Schema, and then applies an XSLT stylesheet.
<pipeline xmlns="http://www.w3.org/ns/xproc">
<xinclude name="included">
<input port="source">
<pipe step="pipeline" port="source"/>
</input>
</xinclude>
<validate-with-xml-schema>
<input port="schema">
<document href="http://example.com/schema.xsd"/>
</input>
</validate-with-xml-schema>
<xslt>
<input port="stylesheet">
<document href="http://example.com/stylesheet.xsl"/>
</input>
</xslt>
</pipeline>