Re: Multiple XSLT Steps with Secondary Outputs

 Thanks Martin and Wendell for the responses.
1. Apologies for not being more clear in the original post. I was hoping that the organization of the XSLTs would be irrelevant beyond the fact that they were creating result documents for the secondary port. So, to clear up any confusion, I've placed the XSLTs inline below.2. I'm testing with the latest versions of both MorganaXProc and XMLCalabash.3. The failures I was getting. . .well, all depends on which permutation of solution I was trying. As mentioned previously I tried everything I could think of. In the version posted originally I was getting an "out of scope" error and now I understand why.4. I have now been able to code a pipeline that produces the output I want. It's close to the solution Wendell outlined. The only change needed was nesting another for-each to store the outputs of the second XSLT. See below.5. So it works. Now I'd like to ask folks with a lot more experience with XProc if this is an approach that is seen as reasonable or ridiculous by the community. The idea of the approach seems unobjectionable to me as it's basically this:
* take a "book" of "chapters"* split the book up into individual chapters* create as many following steps as needed to modify the chapter content, one chapter at a time, where each step produces a sub-folder and all chapters of the book go into that folder for that step
But maybe people already know this is a bad approach. Given what I see working here it would require nesting all subsequent steps which seems sub-optimal. But I welcome all comments and discussion as I'm learning XProc.
<p:declare-step    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    xmlns:xs="http://www.w3.org/2001/XMLSchema"    xmlns:p="http://www.w3.org/ns/xproc"     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">            <p:inline expand-text="false">                <xsl:stylesheet version="3.0">                    <xsl:mode on-no-match="shallow-copy"/>                    <xsl:template match="document">                        <xsl:variable name="href" as="xs:string" select="resolve-uri('spec-split-docs-1/' || @name)"/>                        <xsl:result-document href="{$href}" indent="yes">                            <xsl:copy>                                <xsl:copy-of select="@*"/>                                <xsl:comment>xslt 1</xsl:comment>                                <xsl:copy-of select="*"/>                                            </xsl:copy>                        </xsl:result-document>                    </xsl:template>                </xsl:stylesheet>            </p:inline>        </p:with-input>                </p:xslt>        <p:for-each>        <p:with-input pipe="secondary@create-secondary-documents-1"/>        <p:store href="{base-uri(/)}"/>        <p:xslt name="create-secondary-documents-2">            <p:with-input pipe="secondary@create-secondary-documents-1"/>                        <p:with-input port="stylesheet">                <p:inline expand-text="false">                    <xsl:stylesheet version="3.0">                        <xsl:mode on-no-match="shallow-copy"/>                        <xsl:template match="document">                            <xsl:variable name="href" as="xs:string" select="resolve-uri('spec-split-docs-2/' || @name)"/>                            <xsl:result-document href="{$href}" indent="yes">                                <xsl:copy>                                    <xsl:copy-of select="@*"/>                                    <xsl:comment>xslt 2</xsl:comment>                                    <xsl:copy-of select="*"/>                                                </xsl:copy>                            </xsl:result-document>                        </xsl:template>                    </xsl:stylesheet>                </p:inline>            </p:with-input>        </p:xslt>        <p:for-each>            <p:with-input pipe="secondary@create-secondary-documents-2"/>            <p:store href="{base-uri(/)}"/>        </p:for-each>            </p:for-each>        </p:declare-step>


     
From: Piez, Wendell A. (Fed) 
Sent: Thursday, January 23, 2025 9:29 AM
To: Don Smith <dsmith_lockesmith@yahoo.com>
Subject: RE: Multiple XSLT Steps with Secondary Outputs
 
  
 
Don,
 
  
 
Fishing here in the dark a little bit, but I am thinking you do not need three p:for-each. You need something more like
 
  
 
. xslt creates documents on secondary port
 
. for-each iterates over the sequence, for each
 
    - It stores it (while passing document along)
 
    - it transforms it using another xslt (each one separately)
 
    - it stores this (while passing document along
 
  
 
This assumes your second XSLT works on your documents one by one, not as a set. If the latter, the configuration would depend on how the XSLT is built to accept that sequence.
 
  
 
But if it’s as simple as the above, you don’t need more than one for-each.
 
  
 
HTH! Wendell
 
  
 
From: Don Smith <dsmith_lockesmith@yahoo.com>
Sent: Wednesday, January 22, 2025 9:21 PM
To: xproc-dev@w3.org
Subject: Multiple XSLT Steps with Secondary Outputs
 
  
 
I'm unable to understand how the connections should work between multiple xslt steps where each one has secondary output (and so all but the first have a sequence for an input).
 
  
 
XProc Ref has an example pipeline in the p:xslt step documentation that I'll expand for discussion: https://xprocref.org/3.0/p.xslt.html 
 
  
 
My expansion of the pipeline consists in adding a second XSLT step that follows the first and takes as input the sequence of documents output by the first XSLT step (on secondary port). Both XSLT steps should have their sequence outputs written to disk by p:store.  Here's my expansion of the example (minus the XSLT modules that are referenced):
 
  
 
<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>
 
    
 
    <p:for-each name="step1-store">
 
        <p:with-input pipe="secondary@create-secondary-documents-1"/>
 
        <p:store href="{base-uri(/)}"/>
 
        <p:identity>
 
            <p:with-input pipe="result-uri"/>
 
        </p:identity>
 
    </p:for-each>
 
        
 
    <p:for-each>
 
        <p:xslt name="create-secondary-documents-2">
 
            <p:with-input port="source" pipe="secondary@create-secondary-documents-1"/>
 
            <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>
 
  
 
I've tried every permutation of this I can think of and I can't get any of them to work. I'm sure that I'm missing something fundamental about connections but am not seeing it. Maybe I've got the pipeline concept entirely wrong for the requirement. In any case am asking for folks to enlighten me.
 
  
 
Thanks,
 
  
 
Don
 
  
   

Received on Thursday, 23 January 2025 23:36:09 UTC