Dave Lang
Dave Lang

Reputation: 31

How to copy file from internet to local drive using xsl (file:copy)

I would like to copy 3 files from an internet address to my local drive using xsl.

I don't have a choice re: using xsl - that is what I have to use - not my call.

I've found the file:copy function from expath.org but I can't figure out the syntax.

Could someone post a simple example that works? I'm sure once I see what the function wants from me re: $source and $target etc. I'll be fine.

Upvotes: 0

Views: 1003

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167516

If you want to write a single XSLT 3.0 stylesheet (needs to be run with Saxon 9.8 and command line options -it -xsl:sheet.xsl (you can add -t for debugging to see where Saxon writes to)) downloading three hard-coded URLs you would e.g.

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

    <xsl:param name="url1" as="xs:string?" select="'http://example.com/file1.txt'"/>
    <xsl:param name="url2" as="xs:string?" select="'http://example.com/file2.txt'"/>
    <xsl:param name="url3" as="xs:string?" select="'http://example.com/file2.txt'"/>


    <xsl:param name="source-urls" as="xs:string*" select="$url1, $url2, $url3"/>

    <xsl:template name="xsl:initial-template">
        <xsl:for-each select="$source-urls">
            <xsl:variable name="file-name" select="tokenize(., '/')[last()]"/>
            <xsl:message select="'Writing ', ., ' to ', $file-name"/>
            <xsl:result-document href="{$file-name}" method="text"><xsl:value-of select="unparsed-text(.)"/></xsl:result-document>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Note that unparsed-text might need a second encoding parameter to be able to read the remote file properly (defaults to UTF-8 if not known or readable) and that xsl:result-document writes it out UTF-8 encoded by default I think, you can change it with an encoding attribute. Of course that all is no plain copying like the file:copy.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163312

Extension functions in Saxon, including the EXPath file module, require Saxon-PE and a commercial license.

The EXPath file:copy() function can copy a file from one location to another, but both must be accessible by filename. It therefore can't be used directly to copy a resource that's addressed by URL and retrieved from the internet.

If the resource is XML, I would use the document() function to read it and the xsl:result-document instruction to write it.

If the resource is unparsed text I would use the unparsed-text() function to read it and file:write() to write it.

If the resource is binary (and accessed by HTTP) then I'm not sure there's an off-the-shelf way of reading it in Saxon, although it's easy enough to create a custom extension function for the job.

Upvotes: 0

Related Questions