Skip to content

Instantly share code, notes, and snippets.

@gimsieke gimsieke/xsl-to-zip.xpl
Last active Oct 8, 2015

Embed
What would you like to do?
<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step
xmlns:p="http://www.w3.org/ns/xproc"
xmlns:c="http://www.w3.org/ns/xproc-step"
xmlns:pxp="http://exproc.org/proposed/steps"
version="1.0"
name="xsl-to-zip"
exclude-inline-prefixes="#all">
<p:documentation>Store XSLT transformation results in a zip file.
Invocation:
java -jar path/to/xmlcalabash-1.1.5-96.jar xsl-to-zip.xpl</p:documentation>
<p:output port="result" primary="true" sequence="true">
<p:pipe port="secondary" step="xsl"/>
<p:pipe port="result" step="manifest"/>
<p:pipe port="result" step="zip"/>
</p:output>
<p:serialization port="result" indent="true"/>
<p:import href="http://xmlcalabash.com/extension/steps/library-1.0.xpl"/>
<p:xslt name="xsl" template-name="main">
<p:input port="source">
<p:empty/>
<p:documentation>If there is an input port 'source' on 'xsl-to-zip', you can connect it here,
instead of p:empty:</p:documentation>
<!--<p:pipe port="source" step="xsl-to-zip"/>-->
</p:input>
<p:input port="parameters"><p:empty/></p:input>
<p:input port="stylesheet">
<p:inline>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template name="main">
<xsl:for-each select="(1 to 4)">
<xsl:result-document href="file:/path/doc{.}.xml">
<doc>This is doc #<xsl:value-of select="."/></doc>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
</p:inline>
</p:input>
</p:xslt>
<p:sink/>
<p:for-each name="manifest-entry-iteration">
<p:documentation>Create the manifest entries, see http://exproc.org/proposed/steps/other.html#zip</p:documentation>
<p:iteration-source>
<p:pipe port="secondary" step="xsl">
<p:documentation>The secondary port of the p:xslt step contains the files written via xsl:result-document,
with their respective hrefs as base URIs (so that you can later iterate over them and for example store them to
their base URIs).</p:documentation>
</p:pipe>
</p:iteration-source>
<p:add-attribute attribute-name="name" match="/*">
<p:with-option name="attribute-value" select="replace(base-uri(), '^file:/path/', 'path/')"/>
<p:input port="source">
<p:documentation>We have to create a manifest entry for each output file. The name (intra-zip path) attribute
is computed from the result-document href.</p:documentation>
<p:inline>
<c:entry/>
</p:inline>
</p:input>
</p:add-attribute>
<p:add-attribute attribute-name="href" match="/*">
<p:with-option name="attribute-value" select="base-uri()">
<p:documentation>Caveat: now that the c:entry document appears on the primary input, we have to explicitly
state that base-uri() should be evaluated in the context of the iteration source documents.</p:documentation>
<p:pipe port="current" step="manifest-entry-iteration"/>
</p:with-option>
</p:add-attribute>
</p:for-each>
<p:wrap-sequence wrapper="c:zip-manifest" name="manifest"/>
<pxp:zip name="zip" compression-level="default" compression-method="deflated" command="create">
<p:with-option name="href" select="resolve-uri('out.zip')">
<p:documentation>Stores it relative to the static base URI (the pipeline’s directory)</p:documentation>
</p:with-option>
<p:input port="source">
<p:documentation>The input files (if they were read from disk, we wouldn’t need a document on this port)</p:documentation>
<p:pipe port="secondary" step="xsl"/>
</p:input>
<p:input port="manifest">
<p:documentation>We need a manifest where each entry has a href attribute that matches the corresponding source
document’s base URI and each entry also has a name attribute that specifies the relative location of the stored
file within the zip archive.</p:documentation>
<p:pipe port="result" step="manifest"/>
</p:input>
</pxp:zip>
<p:sink/>
</p:declare-step>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.