Actually, you could consider doing it with a single transform, taking advantage of the new saxon:discard-document() extension function in 8.0:
As you say, you would need to start with an input that contains a list of the 20K documents.
Michael Kay 
Hi Mike,
Is there anything similar for when you mutiple passes of the same document in a single transform, for example:
<xsl:variable name="firstPass">
<xsl:variable name="secondPass">
    <xsl:for-each select="$firstPass">
       <xsl:apply-templates mode="secondpass"/>
<xsl:variable name="finalPass">
    <xsl:for-each select="$secondPass">
       <xsl:apply-templates mode="final"/>
Is there a way of telling Saxon that a variable will no longer be used and can be discarded?