Name
cx:until-unchanged — Iterates to a fixed point.
Synopsis
<cx:until-unchanged
name? = NCName>
(p:output?,
p:log?,
subpipeline)
</cx:until-unchanged>>
Description
The cx:until-unchanged
step is an extension compound
step. There's no provision in the language for defining these steps, but that
doesn't mean implementors can't.
On the first iteration, the cx:until-unchanged
step
provides (on the #current
port) the document that it
reads from the default readable port[3] to the subpipeline it contains.
The subpipeline must produce exactly one output document on
cx:until-unchanged
’s single output port.
On the second and subsequent iterations, the result of the preceding
iteration is provided on the #current
port.
Iteration continues until the document produce is
deep-equal
to the document produced on the
previous iteration.
Here's a trivial example:
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
xmlns:cx="http://xmlcalabash.com/ns/extensions"
name="main" version="1.0">
<p:input port="parameters" kind="parameter"/>
<p:output port="result" sequence="true" primary="true"/>
<p:identity name="id">
<p:input port="source">
<p:inline><doc>1</doc></p:inline>
</p:input>
</p:identity>
<cx:until-unchanged>
<p:output port="result"/>
<p:xslt>
<p:input port="stylesheet">
<p:inline>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="doc">
<xsl:variable name="count" select="xs:integer(.)"/>
<xsl:choose>
<xsl:when test="$count < 5">
<doc><xsl:value-of select="$count+1"/></doc>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
</p:inline>
</p:input>
</p:xslt>
</cx:until-unchanged>
</p:declare-step>
The stylesheet adds one to the integer value of the document that it is styling as long as the value is less than 5.
The result of running this pipeline is that the stylesheet is run five times, producing documents with the “values” 2, 3, 4, 5, 5. At that point the loop terminates and the last document,
<doc>5</doc>
is returned.
[3]
Yes, it's a bug
that there's no equivalent of p:iteration-source
for this
step.