<?xml version="1.0" encoding="UTF-8"?>
<spec role="editors-copy" xmlns:ex="http://expath.org/ns/xmlspec"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <header>
    <title>File Module</title>
    <subtitle>EXPath Candidate Module</subtitle>
    <w3c-designation>w3c-designation</w3c-designation>
    <w3c-doctype>Candidate</w3c-doctype>
    <pubdate>
      <day>17</day>
      <month>May</month>
      <year>2010</year>
    </pubdate>
    <publoc>
      <loc href="http://expath.org/spec/file/20100517"/>
    </publoc>
    <altlocs>
      <loc href="http://expath.org/spec/file/20100517.xml">XML</loc>
    </altlocs>
    <latestloc>
      <loc href="http://expath.org/spec/file"/>
    </latestloc>
    <authlist>
      <author role="editor">
        <name>Matthias Brantner</name>
        <affiliation>28msec GmbH</affiliation>
      </author>
      <author role="contrib">
        <name>Gabriel Petrovay</name>
        <affiliation>28msec GmbH</affiliation>
      </author>
    </authlist>
    <copyright>
      <p/>
    </copyright>
    <abstract>
      <p>This proposal provides a file system API for XPath 2.0. It defines extension functions to
        perform file system related operations such as listing, reading, or writing files. 
		It has been designed to be compatible with XQuery 1.0 and XSLT 2.0, as well as any other XPath 2.0 usage. </p>
    </abstract>
    <status>
      <p/>
    </status>
    <langusage>
      <language>en-US</language>
    </langusage>
    <revisiondesc>
      <p>revisiondesc</p>
    </revisiondesc>
  </header>
  <body>
    <div1>
      <head>Introduction</head>
      <div2>
        <head>Namespace Conventions</head>
        <p>The module defined by this document defines several functions all contained in the namespace
            <code>http://expath.org/ns/file</code>. 
			In this document, the <code>file</code> prefix, when used, is bound to this namespace URI. </p>
        <p>Error codes are defined in the namespace <code>http://expath.org/ns/error</code>. In this
          document, the <code>err</code> prefix, when used, is bound to this namespace URI. </p>
      </div2>
      <div2>
        <head>File Paths vs. URIs</head>
        <p>In order to make the file API more accessible, paths referring to directories of files are specified as strings. The syntax of such strings is implementation defined. 
	However, we strongly recommend that the following forms are accepted and interpreted as described below.</p>
        <ulist>
          <item><p>Operating system paths (absolute or relative paths are accepted):
            <ulist>
              <item><p><code>C:\Test Dir\my file.xml</code>: An absolute path on Windows platforms.</p></item>
              <item><p><code>C:/Test Dir\my file.xml</code>: An absolute path on Windows platforms that tolerates slashes instead of backslashes.</p></item>
              <item><p><code>C:\\\Test Dir//\\my file.xml</code>: An absolute path on Windows platforms that tolerates an arbitrary number of slashes and backslashes.</p></item>
              <item><p><code>/Test Dir/my file.xml</code>: An absolute path on UNIX-based platforms that tolerates an arbitrary number of slashes.</p></item>
              <item><p><code>//Test Dir////my file.xml</code>: An absolute path on UNIX-based platforms.</p></item>
              <item><p><code>my file.xml</code>: A relative path. The file should be searched for starting with the location pointed by the base URI of the current module.</p></item>
            </ulist>
          </p></item>
          <item><p>File URIs (only absolute paths are accepted):
            <ulist>
              <item><p><code>file:///C:/Test%20Dir/my%20file.xml</code>: An absolute path on Windows platforms.</p></item>
              <item><p><code>file:///C:/Test Dir/my file.xml</code>: An absolute path on Windows platforms. The URI tolerates spaces.</p></item>
              <item><p><code>file:///C:/Test%20Dir///my%20file.xml</code>: An absolute path on Windows platforms. The URI tolerates an arbitrary number of slashes.</p></item>
              <item><p><code>file:///Test%20Dir/my%20file.xml</code>: An absolute path on UNIX-based platforms.</p></item>
              <item><p><code>file://localhost/Test%20Dir/my%20file.xml</code>: A URI that accepts <code>localhost</code> or <code>127.0.0.1</code> as the authority of the URI.</p></item>
            </ulist>
          </p></item>
        </ulist>
        In the following, only "paths" is used if referring to a file or directory.
      </div2>
      
      <div2>
        <head>Error management</head>
        <p>Error conditions are identified by an error code (a <code>QName</code>). If such an error
          condition is reached during the execution of the function, a dynamic error is raised, with
          the corresponding error code (as if the standard XPath function <code>error</code> had
          been called). </p>
        <p>Error codes are defined throughout the spec. For too many reasons to enumerate here, the
          file operations can raise an error. In this case, if the error condition is not mentioned
          explicitly in the spec, the implementation must raise an error with an appropriate message
            <bibref ref="errFS001"/>. </p>
      </div2>
    </div1>
    <div1>
      <head>Functions</head>
      <div2>
        <head><code>file:copy</code></head>
        <eg>
sequential <ex:function>file:copy</ex:function>($source as <ex:type>xs:string</ex:type>,
                     $destination as <ex:type>xs:string</ex:type>) as <ex:type>xs:boolean</ex:type>
sequential <ex:function>file:copy</ex:function>($source as <ex:type>xs:string</ex:type>,
                     $destination as <ex:type>xs:string</ex:type>,
                     $overwrite as <ex:type>xs:boolean</ex:type>) as <ex:type>xs:boolean</ex:type></eg>
        <p>This function copies a file given a source and a destination. 
          The operation fails by returning <code>false</code> if the <code>$source</code> path does not point to a file. 
          If the <code>$overwrite</code> parameter is missing or evaluates to <code>false</code>, the function returns false if the destination already exists.
          Otherwise, the destination file, if it exists, will be overwritten.
          The function returns <code>true</code> if the copy operation was successful.
        </p>
      </div2>
      <div2>
        <head><code>file:exists</code></head>
        <eg>
nondeterministic <ex:function>file:exists</ex:function>($fileOrDir as <ex:type>xs:string</ex:type>) as <ex:type>xs:boolean</ex:type></eg>
        <p>Tests if a path is already used in the file system. 
          The function returns <code>true</code> if the file or directory pointed to by the <code>$fileOrDir</code> parameter exists already. Otherwise, the function returns <code>false</code>.</p>
      </div2>
      <div2>
        <head><code>file:files</code></head>
        <eg>
nondeterministic <ex:function>file:files</ex:function>($path as <ex:type>xs:string</ex:type>) as <ex:type>xs:string*</ex:type>
nondeterministic <ex:function>file:files</ex:function>($path as <ex:type>xs:string</ex:type>,
                            $pattern as <ex:type>xs:string</ex:type>) as <ex:type>xs:string*</ex:type>
nondeterministic <ex:function>file:files</ex:function>($path as <ex:type>xs:string</ex:type>,
                            $pattern as <ex:type>xs:string</ex:type>,
                            $recursive as <ex:type>xs:boolean</ex:type>) as <ex:type>xs:string*</ex:type></eg>        
        <p>Lists all files in a given directory.
          The order of the files in the result is not defined. 
		  The special files "." and ".." are never returned. 
          The returned paths are relative to the provided <code>$path</code>. 
          If the optional <code>$pattern</code> parameter is provided, only the file having a name that is matching the given regular expression pattern are
          returned. 
		  An additional <code>$recursive</code> parameter indicates if the search should recurse in the subdirectories.</p>
      </div2>
      <div2>
        <head><code>file:is-directory</code></head>
        <eg>
nondeterministic <ex:function>file:is-directory</ex:function>($dir as <ex:type>xs:string</ex:type>) as <ex:type>xs:boolean</ex:type></eg>
        <p>Tests if a path/URI points to a directory. 
          The function returns <code>true</code> if the path/URI points to a directory.
          Otherwise, it returns <code>false</code>.
          On UNIX-based systems, the root and the volumes roots are considered directories.</p>
      </div2>
      <div2>
        <head><code>file:is-file</code></head>
        <eg>
nondeterministic <ex:function>file:is-file</ex:function>($file as <ex:type>xs:string</ex:type>) as <ex:type>xs:boolean</ex:type></eg>
        <p>Tests if a path points to a regular file.
          The function returns <code>true</code> if the path points to a regular file.
          Otherwise, the function returns <code>false</code>.
        </p>
      </div2>
      <div2>
        <head><code>file:last-modified</code></head>
        <eg>
nondeterministic <ex:function>file:last-modified</ex:function>($fileOrDir as <ex:type>xs:string</ex:type>) as <ex:type>xs:dateTime</ex:type></eg>
        <p>Retrieves the timestamp of the last modification of the file system item (e.g. file, directory, or symbolic link) pointed by the given path (<code>$fileOrDir</code>).</p>
      </div2>
      <div2>
        <head><code>file:mkdir</code></head>
        <eg>
sequential <ex:function>file:mkdir</ex:function>($dir as <ex:type>xs:string</ex:type>) as <ex:type>xs:boolean</ex:type>
sequential <ex:function>file:mkdir</ex:function>($dir as <ex:type>xs:string</ex:type>,
                      $create as <ex:type>xs:boolean</ex:type>) as <ex:type>xs:boolean</ex:type></eg>
        <p>Creates a directory. 
			This function is not recursive. 
			The optional <code>$create</code> parameter indicates that the function should succeed only if the target directory can be created.
          The function returns <code>true</code> if the operation succeeded.
          Otherwise, the function returns <code>false</code>.
        </p>
      </div2>
      <div2>
        <head><code>file:mkdirs</code></head>
        <eg>
sequential <ex:function>file:mkdirs</ex:function>($dir as <ex:type>xs:string</ex:type>) as <ex:type>xs:boolean</ex:type>
sequential <ex:function>file:mkdirs</ex:function>($dir as <ex:type>xs:string</ex:type>,
                       $create as <ex:type>xs:boolean</ex:type>) as <ex:type>xs:boolean</ex:type></eg>
        <p>Creates directories recursively. The optional <code>$create</code> parameter indicates that
          the function should succeed only if the target directory can be created.
          The function returns <code>true</code> if the operation succeeded.
          Otherwise, the function returns <code>false</code>.
        </p>
      </div2>
      <div2>
        <head><code>file:path-separator</code></head>
        <eg>
<ex:function>file:path-separator</ex:function>() as <ex:type>xs:string</ex:type></eg>
        <p>This function returns the file path separator used by the operating system. For example, it returns "/" on Unix-based platforms or "\" on Windows platforms.</p>
      </div2>
      <div2>
        <head><code>file:path-to-full-path</code></head>
        <eg>
<ex:function>file:path-to-full-path</ex:function>($path as <ex:type>xs:string</ex:type>) as <ex:type>xs:string</ex:type></eg>
        <p>Transforms a path into a full operating system path. The resulting URI must have the file://
          scheme. The operation is performed regardless the existence of a file or directory referred to by the provided path.</p>
      </div2>
      <div2>
        <head><code>file:path-to-uri</code></head>
        <eg>
<ex:function>file:path-to-uri</ex:function>($path as <ex:type>xs:string</ex:type>) as <ex:type>xs:anyURI</ex:type></eg>
        <p>Transforms a file system path into a URI with the file:// scheme. No checks are performed regardless of the existence of a fil or directory referred to by the provided file system path.</p>
      </div2>
      <div2>
        <head><code>file:read</code></head>
        <eg>
nondeterministic <ex:function>file:read</ex:function>($file as <ex:type>xs:string</ex:type>) as <ex:type>xs:base64Binary</ex:type></eg>
        <p>Reads the content of a file pointed to by the <code>$file</code> parameter and returns a Base64 representation of the content.</p>
      </div2>
      <div2>
        <head><code>file:read-html</code></head>
        <eg>
nondeterministic <ex:function>file:read-html</ex:function>($file as <ex:type>xs:string</ex:type>,
                                $tidyOptions as <ex:type>xs:string</ex:type>) as <ex:type>xs:string</ex:type></eg>
        <p>Read the content of the HTML file pointed to by the <code>$file</code> parameters and returns it as a string. 
         </p>
      </div2>
      <div2>
        <head><code>file:read-text</code></head>
        <eg>
nondeterministic <ex:function>file:read-text</ex:function>($file as <ex:type>xs:string</ex:type>) as <ex:type>xs:string</ex:type></eg>
        <p>Reads the content of a file and returns the string representation of the content.</p>
      </div2>
      <div2>
        <head><code>file:read-xml</code></head>
        <eg>
nondeterministic <ex:function>file:read-xml</ex:function>($file as <ex:type>xs:string</ex:type>) as <ex:type>node()</ex:type>
nondeterministic <ex:function>file:read-xml</ex:function>($file as <ex:type>xs:string</ex:type>,
                               $tidy as <ex:type>xs:boolean</ex:type>) as <ex:type>node()</ex:type></eg>
        <p>Reads a file and returns the parsed an XML document.
          If the <code>$tidy</code> parameter is present and evaluates to <code>true</code>, the implementation might perform a cleaning step (e.g. as performed by the tidy library) in order to make sure that a valid XML document is obtained.
          If the <code>$tidy</code> parameter is not present or evaluates to <code>false</code> and the file does not contain a well-formed XML document, an error is raised (TODO error code).
          Cleaning documents before parsing in order to make them well-formed might be useful for HTML documents.
        </p>
        
      </div2>
      <div2>
        <head><code>file:remove</code></head>
        <eg>
sequential <ex:function>file:remove</ex:function>($fileOrDir as <ex:type>xs:string</ex:type>) as <ex:type>xs:boolean</ex:type></eg>
        <p>Delete a file or a directory from the file system. This operation is not recursive.
          The function returns <code>false</code> if the operation failed (e.g. if a non-empty directory should be deleted or the file or directory does not exist).
        Otherwise, the function returns <code>true</code>.</p>
      </div2>
      <div2>
        <head><code>file:write</code></head>
        <eg>
sequential <ex:function>file:write</ex:function>($file as <ex:type>xs:string</ex:type>,
                      $content as <ex:type>item()*</ex:type>,
                      $serializer-params as <ex:type>node()*</ex:type>) as <ex:type>xs:boolean</ex:type>
sequential <ex:function>file:write</ex:function>($file as <ex:type>xs:string</ex:type>,
                      $content as <ex:type>item()*</ex:type>,
                      $serializer-params as <ex:type>node()*</ex:type>,
                      $append as <ex:type>xs:boolean</ex:type>) as <ex:type>xs:boolean</ex:type> 
        </eg>
        <p>Write a sequence of items to a file. This operation creates a new file or appends the
          serialized content to the file pointed by the given path/URI. If the <code>$append</code> flag
          is true and the file does not exist, a new one is created.</p>
        <p>The <code>$serializer-params</code> parameter is used to set the corresponding serialization parameter defined in <bibref ref="xserial"/>, as defined for the XPath 2.1 function fn:serialize().</p>
        <p>The function returns <code>true</code> if the file was written successfully, or <code>false</code> otherwise.</p>
      </div2>
    </div1>
  </body>
  <back>
    <div1>
      <head>References</head>
      <blist>
        <bibl xlink:actuate="onRequest" xlink:show="replace" id="xserial" key="Serialization">
          <loc href="http://www.w3.org/TR/xslt-xquery-serialization/"> XSLT 2.0 and XQuery 1.0
            Serialization </loc>. Scott Boag, Michael Kay, Joanne Tong, Norman Walsh, and Henry
          Zongaro, editors. W3C Recommendation. 23 January 2007. </bibl>
        <bibl id="fo11" key="F&amp;O 1.1">
          <loc href="http://www.w3.org/TR/xpath-functions-11/"> XPath and XQuery Functions and
            Operators 1.1 </loc>. Michael Kay, editor. W3C Working Draft. 15 January 2009. </bibl>
        <bibl id="xslt20" key="XSLT 2.0">
          <loc href="http://www.w3.org/TR/xslt20/">XSL Transformations (XSLT) Version 2.0</loc>.
          Michael Kay, editor. W3C Recommendation. 23 January 2007. </bibl>
      </blist>
    </div1>
    <div1>
      <head>Summary of Error Conditions</head>
      <blist>
        <bibl id="errFS001" key="err:FS001">A file system error occurred.</bibl>
      </blist>
    </div1>
  </back>
</spec>
