p:directory-list — Lists the files, directories, and other contents of a directory on the filesystem.
<p:declare-step
type
="
p:directory-list
"
>
<p:output
port
="
result
"
/>
<p:option
name
="
path
"
required
="
true
"
/>
<!--
anyURI -->
<p:option
name
="
include-filter
"
/>
<!--
RegularExpression -->
<p:option
name
="
exclude-filter
"
/>
<!--
RegularExpression -->
</p:declare-step>
The p:directory-list step lists the contents of the specified directory on the filesystem.
The value of the path option is interpreted as an IRI reference. If it is relative, it is made absolute against the base URI of the element on which it is specified.
The values of the include-filter and exclude-filter options are regular expression as specified in [XPath 2.0 Functions and Operators], section 7.61 “Regular Expression Syntax”.
If the include-filter pattern matches the name of a filesystem object, that object is included in the output. If the exclude-filter pattern matches the name, that object is excluded from the output. If both options are provided, the include filter is processed first, then the exclude filter.
Processors must support directory paths whose scheme is file:; they may also support other schemes, but the semantics of those schemes is implementation-defined.
The “c:directory” document that the p:directory-list step produces lists the included filesystem objects. The base URI of the document is the directory path read; it has a name attribute that is the last segment of the directory path.
The children of the c:directory element represent each of the included filesystem objects:
A c:directory is produced for each subdirectory.
A c:file is produced for each file.
If the filesystem supports “special” objects (devices, links, etc.), those may be represented with c:other elements. Exactly what constitutes “special” is implementation-defined and may vary by platform.
The c:directory-list step does not process subdirectories recursively. For recursive processing, see ex:recursive-directory-list.
Each of the elements c:file, c:directory, and c:other has a name whose value is a relative IRI reference, giving the (local) file or directory name. Implementations may include additional attributes.
What's in my “XProc book” directory? Let's see! (This example pipeline is in a directory a couple of levels below the main book directory, hence the “../..”.)
1 <p:pipeline xmlns:p="http://www.w3.org/ns/xproc" version="1.0"> <p:directory-list path="../.."/> 5 </p:pipeline>
Output |
---|
1 <c:directory xmlns:c="http://www.w3.org/ns/xproc-step"
name="src"
xml:base="file:/projects/xproc/src/">
<c:directory name=".svn"/>
5 <c:file name="bibl.xml"/>
<c:file name="bibl.xml~"/>
<c:file name="book.html"/>
<c:file name="book.html~"/>
<c:file name="book.xml"/>
10 <c:file name="book.xml~"/>
<c:file name="ch01.xml"/>
<c:file name="ch02.xml"/>
<c:file name="ch03.xml"/>
<c:file name="ch04.xml"/>
15 <c:file name="ch04.xml~"/>
<c:file name="ch05.xml"/>
<c:file name="ch05.xml~"/>
<c:file name="ch06.xml"/>
<c:file name="ch06.xml~"/>
20 <c:file name="ch07.xml"/>
<c:file name="ch07.xml~"/>
<c:file name="ch08.xml"/>
<c:file name="ch08.xml~"/>
<c:directory name="compound"/>
25 <c:directory name="core"/>
<c:directory name="examples"/>
<c:directory name="fileutils"/>
<c:file name="glossary.xml"/>
<c:file name="glossary.xml~"/>
30 <c:file name="Makefile"/>
<c:file name="Makefile~"/>
<c:directory name="osutils"/>
<c:file name="schemas.xml"/>
<c:file name="schemas.xml~"/>
35 <c:file name="template.xml"/>
<c:directory name="utils"/>
<c:directory name="x"/>
<c:file name="xc01.xml"/>
<c:file name="xc01.xml~"/>
40 <c:file name="xc02.xml"/>
<c:directory name="xpl"/>
<c:file name="xproc.xpr"/>
</c:directory>
|
If you only want the XML files, use a filter:
1 <p:pipeline xmlns:p="http://www.w3.org/ns/xproc" version="1.0"> <p:directory-list path="../.." include-filter="^.*\.xml$"/> 5 </p:pipeline>
Output |
---|
1 <c:directory xmlns:c="http://www.w3.org/ns/xproc-step"
name="src"
xml:base="file:/projects/xproc/src/">
<c:file name="bibl.xml"/>
5 <c:file name="book.xml"/>
<c:file name="ch01.xml"/>
<c:file name="ch02.xml"/>
<c:file name="ch03.xml"/>
<c:file name="ch04.xml"/>
10 <c:file name="ch05.xml"/>
<c:file name="ch06.xml"/>
<c:file name="ch07.xml"/>
<c:file name="ch08.xml"/>
<c:file name="glossary.xml"/>
15 <c:file name="schemas.xml"/>
<c:file name="template.xml"/>
<c:file name="xc01.xml"/>
<c:file name="xc02.xml"/>
</c:directory>
|
The standard p:directory-list step does not build an entire tree, it only returns the contents of a single directory. But it's easy to write your own recursive processor directly in XProc:
1 <p:declare-step xmlns:p="http://www.w3.org/ns/xproc" xmlns:c="http://www.w3.org/ns/xproc-step" xmlns:cx="http://xmlcalabash.com/ns/extensions" type="cx:recursive-directory-list" 5 version="1.0"> <p:output port="result"/> <p:option name="path" required="true"/> <p:option name="include-filter"/> <p:option name="exclude-filter"/> 10 <p:option name="depth" select="-1"/> <p:choose> <p:when test="p:value-available('include-filter') and p:value-available('exclude-filter')"> 15 <p:directory-list> <p:with-option name="path" select="$path"/> <p:with-option name="include-filter" select="$include-filter"/> <p:with-option name="exclude-filter" select="$exclude-filter"/> </p:directory-list> 20 </p:when> <p:when test="p:value-available('include-filter')"> <p:directory-list> <p:with-option name="path" select="$path"/> 25 <p:with-option name="include-filter" select="$include-filter"/> </p:directory-list> </p:when> <p:when test="p:value-available('exclude-filter')"> 30 <p:directory-list> <p:with-option name="path" select="$path"/> <p:with-option name="exclude-filter" select="$exclude-filter"/> </p:directory-list> </p:when> 35 <p:otherwise> <p:directory-list> <p:with-option name="path" select="$path"/> </p:directory-list> 40 </p:otherwise> </p:choose> <p:viewport match="/c:directory/c:directory"> <p:variable name="name" select="/*/@name"/> 45 <p:choose> <p:when test="$depth != 0"> <p:choose> <p:when test="p:value-available('include-filter') 50 and p:value-available('exclude-filter')"> <cx:recursive-directory-list> <p:with-option name="path" select="concat($path,'/',$name)"/> <p:with-option name="include-filter" select="$include-filter"/> <p:with-option name="exclude-filter" select="$exclude-filter"/> 55 <p:with-option name="depth" select="$depth - 1"/> </cx:recursive-directory-list> </p:when> <p:when test="p:value-available('include-filter')"> 60 <cx:recursive-directory-list> <p:with-option name="path" select="concat($path,'/',$name)"/> <p:with-option name="include-filter" select="$include-filter"/> <p:with-option name="depth" select="$depth - 1"/> </cx:recursive-directory-list> 65 </p:when> <p:when test="p:value-available('exclude-filter')"> <cx:recursive-directory-list> <p:with-option name="path" select="concat($path,'/',$name)"/> 70 <p:with-option name="exclude-filter" select="$exclude-filter"/> <p:with-option name="depth" select="$depth - 1"/> </cx:recursive-directory-list> </p:when> 75 <p:otherwise> <cx:recursive-directory-list> <p:with-option name="path" select="concat($path,'/',$name)"/> <p:with-option name="depth" select="$depth - 1"/> </cx:recursive-directory-list> 80 </p:otherwise> </p:choose> </p:when> <p:otherwise> <p:identity/> 85 </p:otherwise> </p:choose> </p:viewport> </p:declare-step>
The slightly convoluted p:choose is a consequence of limitations in how p:value-available works; see Section 3, “p:value-available”.