xsltxpath-2.0xproc

XProc p:store href variable when using xsl:result-document


I'm using XProc to run an XSLT that spits out numerous result-documents (using the xsl:result-document). I'm unsure how to go about adding a variable for the @href in the step. I've got the below XProc:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0">
<p:input port="source">
    <p:empty/>
</p:input>

<p:xslt name="pagelist">
    <p:input port="stylesheet">
        <p:document href="file:/C:/page-list.xsl"/>
    </p:input>
    <p:input port="source">
        <p:document href="file:/C:/toc.xml"/>
    </p:input>
    <p:input port="parameters">
        <p:empty/>
    </p:input>
</p:xslt>
<p:store name="pagelist" indent="true">
    <p:with-option name="method" select="'xml'" />
    <p:with-option name="href" select="" />
</p:store>

How do I add a variable in the XProc that will match the output filename from the xsl:result-document?

XSLT snippet, if needed:

<xsl:result-document href="{xhtml:a[@class='ref-uri']/@id}_pagelist.xml" method="xml" include-content-type="no" indent="no">

Solution

  • Using Calabash 1.1.30 from the command line I was able to get the following to work:

    <?xml version="1.0" encoding="UTF-8"?>
    <p:declare-step xmlns:p="http://www.w3.org/ns/xproc" xpath-version="2.0"
        xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0">
        <p:input port="source">
            <p:empty/>
        </p:input>
    
        <p:output port="result" primary="true" sequence="true">
            <p:pipe port="result" step="secondary-storage"/>
        </p:output>
    
        <p:xslt name="xslt-pagelist" version="2.0">
            <p:input port="stylesheet">
                <p:document href="page-list.xsl"/>
            </p:input>
            <p:input port="source">
                <p:document href="toc.xml"/>
            </p:input>
            <p:input port="parameters">
                <p:empty/>
            </p:input>
        </p:xslt>
    
        <p:store href="toc-list.html"/>
    
        <p:for-each name="secondary-storage">
            <p:iteration-source select=".">
                <p:pipe port="secondary" step="xslt-pagelist"/>
            </p:iteration-source>
            <p:output port="result">
                <p:pipe port="result" step="store"/>
            </p:output>
            <p:store name="store">
                <p:with-option name="href" select="document-uri(.)"/>
            </p:store>
        </p:for-each>
    
    </p:declare-step>
    

    So basically a p:for-each over a p:iteration-source that uses the secondary result output port from the p:xslt step and then inside simply uses document-uri(.) to have the result URI. All this requires xpath-version="2.0".

    Somehow oXygen 22 doesn't run the code but gives me an access denied error, it seems to be set up to write secondary documents to the oXygen installation directory which with normal Windows security settings is not allowed and is not a place where you want result files anyhow; to fix that problem I have adjusted the XProc to have the XML input as a input source to the whole XProc script, then in the p:xslt step I can use the function p:base-uri to set the output-base-uri for XSLT:

    <?xml version="1.0" encoding="UTF-8"?>
    <p:declare-step xmlns:p="http://www.w3.org/ns/xproc" xpath-version="2.0"
        xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0">
        <p:input port="source">
            <p:document href="toc.xml"/>
        </p:input>
    
        <p:output port="result" primary="true" sequence="true">
            <p:pipe port="result" step="secondary-storage"/>
        </p:output>
    
        <p:xslt name="xslt-pagelist" version="2.0">
            <p:with-option name="output-base-uri" select="p:base-uri()"/>
            <p:input port="stylesheet">
                <p:document href="page-list.xsl"/>
            </p:input>
            <p:input port="parameters">
                <p:empty/>
            </p:input>
        </p:xslt>
    
        <p:store href="toc-list.html"/>
    
        <p:for-each name="secondary-storage">
            <p:iteration-source select=".">
                <p:pipe port="secondary" step="xslt-pagelist"/>
            </p:iteration-source>
            <p:output port="result">
                <p:pipe port="result" step="store"/>
            </p:output>
            <p:store name="store">
                <p:with-option name="href" select="document-uri(.)"/>
            </p:store>
        </p:for-each>
    
    </p:declare-step>
    

    That way Calabash from the command line and within oXygen behave the same, writing the results to the same directory as the input source comes from.