Re: Multiple XSLT Steps with Secondary Outputs

Hi Don,

It’s a little hard to understand what you want this pipeline to do, so I’m making a few guesses. You didn’t say what the stylesheets do. Here’s
what I invented for testing:

spec-split-docs-1.xsl:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xs"
                version="3.0">

<xsl:output method="xml" encoding="utf-8" indent="no"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="/">
  <xsl:result-document href="split1a.xml"><doc/></xsl:result-document>
  <xsl:result-document href="split1b.xml"><doc/></xsl:result-document>
  <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

spec-split-docs-2.xsl:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xs"
                version="3.0">

<xsl:output method="xml" encoding="utf-8" indent="no"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="/">
  <xsl:result-document href="split2a.xml"><doc/></xsl:result-document>
  <xsl:result-document href="split2b.xml"><doc/></xsl:result-document>
  <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

> <p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">
>     <p:input port="source"/>
>     <p:output port="result" />
>     
>     <p:xslt name="create-secondary-documents-1">
>         <p:with-input port="stylesheet" href="spec-split-docs-1.xsl"/>
>     </p:xslt>

This is going to produce a single document on the result port and
a sequenceon the secondary port.

>     <p:for-each name="step1-store">
>         <p:with-input pipe="secondary@create-secondary-documents-1"/>

Okay, we’re going to iterate over the secondary documents.

>         <p:store href="{base-uri(/)}"/>

And store them.

>         <p:identity>
>             <p:with-input pipe="result-uri"/>
>         </p:identity>

And output the result URIs.

>     </p:for-each>
>         
>     <p:for-each>
>         <p:xslt name="create-secondary-documents-2">
>             <p:with-input port="source" pipe="secondary@create-secondary-documents-1"/>

This is going to iterate over each of the output URIs and then call the XSLT step passing all of the documents from the secondary port on
create-secondary-documents-1 each time.

I think that’s the only bit that’s really confusing.

>             <p:with-input port="stylesheet" href="spec-split-docs-2.xsl"/>
>         </p:xslt>
>     </p:for-each>    
>     
>     <p:for-each name="step2-store">
>         <p:with-input pipe="secondary@create-secondary-documents-2"/>
>         <p:store href="{base-uri(/)}"/>
>         <p:identity>
>             <p:with-input pipe="result-uri"/>
>         </p:identity>
>     </p:for-each>
>     
> </p:declare-step>

Here’s my version:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
                xmlns:cx="http://xmlcalabash.com/ns/extensions"
                name="main" version="3.0">
    
    <p:input port="source"/>
    <p:output port="result" sequence="true"/>
    
    <p:xslt name="create-secondary-documents-1">
      <p:with-input port="stylesheet" href="spec-split-docs-1.xsl"/>
    </p:xslt>

    <p:for-each name="step1-store">
      <p:with-input pipe="secondary@create-secondary-documents-1"/>
      <p:store href="{base-uri(/)}" message="store1: {base-uri(/)}"/>
      <p:identity>
        <p:with-input pipe="result-uri"/>
      </p:identity>
    </p:for-each>

    <!-- Iterate over each of the secondary documents from the first xslt step. For each one, run the second xslt. The output of this step is all of the documents on the xslt secondary port -->

    <p:for-each>
      <p:with-input pipe="secondary@create-secondary-documents-1"/>
      <p:output port="result" sequence="true"
                pipe="secondary@create-secondary-documents-2"/>
      <p:xslt name="create-secondary-documents-2">
        <p:with-input port="stylesheet" href="spec-split-docs-2.xsl"/>
      </p:xslt>
    </p:for-each>    
    
    <p:for-each name="step2-store">
      <p:store href="{base-uri(/)}" message="store2: {base-uri(/)}"/>
      <p:identity>
        <p:with-input pipe="result-uri"/>
      </p:identity>
    </p:for-each>

</p:declare-step>

Whether it does the “right thing” sort of depends on whether or not I guessed correctly. But hopefully that’s useful.

                                        Be seeing you,
                                          norm

--
Norm Tovey-Walsh <ndw@nwalsh.com>
https://norm.tovey-walsh.com/

> I am but a blood, bone, and muscle platform that holds up the camera.
> The pictures take themselves.--James Tallon

Received on Friday, 24 January 2025 17:43:03 UTC