<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" xmlns:c="http://www.w3.org/ns/xproc-step" xmlns:d="http://www.daisy.org/ns/pipeline/data" xmlns:px="http://www.daisy.org/ns/pipeline/xproc" xmlns:letex="http://www.le-tex.de/namespace" xmlns:pxi="http://www.daisy.org/ns/pipeline/xproc/internal" xmlns:cx="http://xmlcalabash.com/ns/extensions" type="px:fileset-unzip" version="1.0" name="main"> <p:documentation>A step for extracting information out of ZIP archives. Compatible with EXProcs `pxp:unzip` and Calabash's `cx:unzip`, but with additional options that default to the same behaviour as `pxp:unzip`.</p:documentation> <p:output port="result" sequence="true" primary="true"> <p:pipe port="result" step="result"/> </p:output> <p:output port="fileset"> <p:pipe port="result" step="fileset"/> </p:output> <p:option name="href" required="true"/> <p:option name="file"/> <p:option name="content-type"/> <p:option name="unzipped-basedir"/> <p:option name="load-to-memory"/> <p:option name="store-to-disk" select="'false'"/> <p:option name="overwrite" select="'false'"/> <p:import href="fileset-library.xpl"/> <p:import href="http://www.daisy.org/pipeline/modules/file-utils/library.xpl"/> <p:import href="http://www.daisy.org/pipeline/modules/zip-utils/library.xpl"/> <p:import href="http://www.daisy.org/pipeline/modules/common-utils/library.xpl"/> <p:choose name="choose"> <p:when test="p:value-available('load-to-memory')"> <p:output port="result" sequence="true" primary="true"> <p:pipe port="result" step="choose.inner"/> </p:output> <p:output port="otherwise"> <p:pipe port="otherwise" step="choose.inner"/> </p:output> <p:choose name="choose.inner"> <p:when test="p:value-available('file') and $load-to-memory = 'false'"> <p:output port="result" sequence="true" primary="true"/> <p:output port="otherwise"> <p:inline exclude-inline-prefixes="#all"> <c:otherwise>false</c:otherwise> </p:inline> </p:output> <px:unzip> <p:with-option name="href" select="$href"/> </px:unzip> <p:delete> <p:with-option name="match" select="concat('/*/*[not(@name=''',replace($file,'''',''''''),''')]')"/> </p:delete> </p:when> <p:when test="not(p:value-available('file')) and $load-to-memory = 'true'"> <p:output port="result" sequence="true" primary="true"/> <p:output port="otherwise"> <p:inline exclude-inline-prefixes="#all"> <c:otherwise>false</c:otherwise> </p:inline> </p:output> <px:unzip> <p:with-option name="href" select="$href"/> </px:unzip> <p:delete match="/*/*[ends-with(@name,'/')]"/> <p:for-each> <p:iteration-source select="/*/*"/> <p:variable name="entry-name" select="/*/@name"/> <p:choose> <p:when test="p:value-available('content-type')"> <px:unzip> <p:with-option name="href" select="$href"/> <p:with-option name="file" select="$entry-name"/> <p:with-option name="content-type" select="$content-type"/> </px:unzip> </p:when> <p:otherwise> <px:unzip content-type="application/octet-stream"> <p:with-option name="href" select="$href"/> <p:with-option name="file" select="$entry-name"/> </px:unzip> </p:otherwise> </p:choose> <p:choose> <p:when test="p:value-available('unzipped-basedir')"> <p:variable name="basedir" select="if (ends-with($unzipped-basedir,'/')) then $unzipped-basedir else concat($unzipped-basedir,'/')"/> <p:add-attribute match="/*" attribute-name="xml:base"> <p:with-option name="attribute-value" select="resolve-uri($entry-name, $basedir)"/> </p:add-attribute> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> </p:for-each> </p:when> <p:otherwise> <p:output port="result" sequence="true" primary="true"/> <p:output port="otherwise"> <p:inline exclude-inline-prefixes="#all"> <c:otherwise>true</c:otherwise> </p:inline> </p:output> <p:identity> <p:input port="source"> <p:empty/> </p:input> </p:identity> </p:otherwise> </p:choose> </p:when> <p:otherwise> <p:output port="result" sequence="true" primary="true"/> <p:output port="otherwise"> <p:inline exclude-inline-prefixes="#all"> <c:otherwise>true</c:otherwise> </p:inline> </p:output> <p:identity> <p:input port="source"> <p:empty/> </p:input> </p:identity> </p:otherwise> </p:choose> <p:choose> <p:xpath-context> <p:pipe port="otherwise" step="choose"/> </p:xpath-context> <p:when test="not(/*/text()='true')"> <p:identity/> </p:when> <p:otherwise> <p:choose> <p:when test="p:value-available('file') and p:value-available('content-type')"> <px:unzip> <p:with-option name="href" select="$href"/> <p:with-option name="file" select="$file"/> <p:with-option name="content-type" select="$content-type"/> </px:unzip> </p:when> <p:when test="p:value-available('file')"> <px:unzip> <p:with-option name="href" select="$href"/> <p:with-option name="file" select="$file"/> </px:unzip> </p:when> <p:otherwise> <px:unzip> <p:with-option name="href" select="$href"/> </px:unzip> </p:otherwise> </p:choose> <p:choose> <p:when test="p:value-available('file') and p:value-available('unzipped-basedir')"> <p:variable name="basedir" select="if (ends-with($unzipped-basedir,'/')) then $unzipped-basedir else concat($unzipped-basedir,'/')"/> <p:add-attribute match="/*" attribute-name="xml:base"> <p:with-option name="attribute-value" select="resolve-uri(replace($file,'.*/',''), $basedir)"/> </p:add-attribute> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> </p:otherwise> </p:choose> <p:identity name="result"/> <p:sink/> <p:choose> <p:when test="$store-to-disk = 'true' and not(p:value-available('unzipped-basedir'))"> <px:error code="PZU001" message="When store-to-disk='true' then unzipped-basedir must also be defined"/> </p:when> <p:when test="$store-to-disk = 'true'"> <p:variable name="basedir" select="if (ends-with($unzipped-basedir,'/')) then $unzipped-basedir else concat($unzipped-basedir,'/')"/> <p:choose> <p:when test="p:step-available('letex:unzip')"> <p:choose> <p:when test="p:value-available('file')"> <letex:unzip> <p:with-option name="zip" select="$href"/> <p:with-option name="dest-dir" select="$basedir"/> <p:with-option name="overwrite" select="if ($overwrite = 'true') then 'yes' else 'no'"/> <p:with-option name="file" select="$file"/> </letex:unzip> </p:when> <p:otherwise> <letex:unzip> <p:with-option name="zip" select="$href"/> <p:with-option name="dest-dir" select="$basedir"/> <p:with-option name="overwrite" select="if ($overwrite = 'true') then 'yes' else 'no'"/> </letex:unzip> </p:otherwise> </p:choose> <p:rename match="/*" new-name="d:fileset"/> <p:rename match="/*/*" new-name="d:file"/> <p:rename match="/*/*/@name" new-name="href"/> <p:viewport match="/*/*"> <p:add-attribute match="/*" attribute-name="original-href"> <p:with-option name="attribute-value" select="resolve-uri(/*/@href, base-uri(.))"/> </p:add-attribute> </p:viewport> </p:when> <p:otherwise> <p:choose> <p:when test="p:value-available('file')"> <p:add-attribute match="/*/*" attribute-name="name"> <p:input port="source"> <p:inline exclude-inline-prefixes="#all"> <c:zipfile> <c:file/> </c:zipfile> </p:inline> </p:input> <p:with-option name="attribute-value" select="$file"/> </p:add-attribute> </p:when> <p:otherwise> <px:unzip> <p:with-option name="href" select="$href"/> </px:unzip> </p:otherwise> </p:choose> <px:message severity="WARN" message="letex:unzip is not available (you are probably running this outside of the DAISY Pipeline 2 framework); unzipping will be slow for big ZIP files"/> <p:for-each> <p:iteration-source select="/*/c:file"/> <p:variable name="entry-name" select="/*/@name"/> <p:variable name="target-href" select="resolve-uri(if (p:value-available('file')) then replace($entry-name,'.*/','') else $entry-name, $basedir)"/> <p:try> <p:group> <px:info> <p:with-option name="href" select="$target-href"/> </px:info> </p:group> <p:catch> <p:identity> <p:input port="source"> <p:empty/> </p:input> </p:identity> </p:catch> </p:try> <p:count/> <p:choose> <p:when test="/*/text() = '0' or $overwrite = 'true'"> <px:unzip content-type="application/octet-stream"> <p:with-option name="href" select="$href"/> <p:with-option name="file" select="$entry-name"/> </px:unzip> <p:store name="store-file" cx:decode="true" encoding="base64"> <p:with-option name="href" select="$target-href"/> </p:store> <p:rename match="/*" new-name="d:file"> <p:input port="source"> <p:pipe port="result" step="store-file"/> </p:input> </p:rename> <p:add-attribute match="/*" attribute-name="original-href"> <p:with-option name="attribute-value" select="/*/text()"/> </p:add-attribute> <p:delete match="/*/text()"/> <p:add-attribute match="/*" attribute-name="href"> <p:with-option name="attribute-value" select="replace(/*/@original-href,'.*/','')"/> </p:add-attribute> <p:wrap-sequence wrapper="d:fileset"/> <p:add-attribute match="/*" attribute-name="xml:base"> <p:with-option name="attribute-value" select="replace(/*/*/@original-href,'[^/]+$','')"/> </p:add-attribute> </p:when> <p:otherwise> <px:fileset-create> <p:with-option name="base" select="replace($target-href,'[^/]+$','')"/> </px:fileset-create> <px:fileset-add-entry> <p:with-option name="href" select="replace($target-href,'.*/','')"/> </px:fileset-add-entry> </p:otherwise> </p:choose> </p:for-each> <px:fileset-join/> </p:otherwise> </p:choose> </p:when> <p:when test="p:value-available('file')"> <p:choose> <p:when test="p:value-available('unzipped-basedir')"> <p:variable name="basedir" select="if (ends-with($unzipped-basedir,'/')) then $unzipped-basedir else concat($unzipped-basedir,'/')"/> <px:fileset-create> <p:with-option name="base" select="$basedir"/> </px:fileset-create> </p:when> <p:otherwise> <px:fileset-create/> </p:otherwise> </p:choose> <px:fileset-add-entry> <p:with-option name="href" select="replace($file,'.*/','')"/> </px:fileset-add-entry> </p:when> <p:otherwise> <px:unzip> <p:with-option name="href" select="$href"/> </px:unzip> <p:rename match="/*" new-name="d:fileset"/> <p:choose> <p:when test="p:value-available('unzipped-basedir')"> <p:variable name="basedir" select="if (ends-with($unzipped-basedir,'/')) then $unzipped-basedir else concat($unzipped-basedir,'/')"/> <p:add-attribute match="/*" attribute-name="xml:base"> <p:with-option name="attribute-value" select="$basedir"/> </p:add-attribute> </p:when> <p:otherwise> <p:identity/> </p:otherwise> </p:choose> <p:delete match="/*/@*[not(name()='xml:base')]"/> <p:delete match="/*/*[ends-with(@name,'/')]"/> <p:viewport match="/*/*"> <p:rename match="/*" new-name="d:file"/> <p:add-attribute match="/*" attribute-name="href"> <p:with-option name="attribute-value" select="/*/@name"/> </p:add-attribute> </p:viewport> <p:delete match="/*/*/@*[not(name()='href')]"/> </p:otherwise> </p:choose> <p:identity name="fileset"/> <p:sink/> </p:declare-step>