Thank you for this clarification, Christian. In my opinion, it is a pity that the functions file:children and file:descendants do not return absolute paths - I see only disadvantages. When the argument is a relative path, you get back relative paths which only make sense in the context of the current working directory. If passing them on to a file:* function, that is fine (as your example shows), if passing them on to other functions, especially the key functions returning node trees - doc(), json:doc(), csv:doc() - they do not work and have first to be resolved to absolute paths, e.g. using file:path-to-native(). The function result thus must be used differently dependent on which function will consume it. Another shortcoming - if the file paths are wanted as paths - e.g. written into a report - relative paths to be resolved against the current working directory will probably be useless, so again they must first be resolved before being used. Last and least, the paths are often ugly, like "../xslt". Paths relative to the current working directory are very important as user input, hence their consistent use in the file module as input parameter makes much sense, especially when writing tools. But they are very rarely (if ever) to be preferred over absolute paths in other situations. (This is in sharp contrast to relative paths to be resolved against the containing resource's base URI.) I cannot imagine a situation where I would appreciate to get a CWD-based relative path from a function, rather than an absolute path. However, probably there is a rationale, or an important usecase, behind the current behaviour which I overlooked. Kind regards,Hans-Jürgen
Am Montag, 26. September 2022 um 09:50:16 MESZ hat Christian Grün christian.gruen@gmail.com Folgendes geschrieben:
Thanks for your discussion. I’ll give some comments to…
1. Returned paths of file:descendants and file:children
The paths returned by these functions start with the directory argument specified by the user. The argument may point to a relative or absolute path. Code can often be simplified by replacing file:list with file:children or file:descendants:
let $root := 'a/b/c/' for $path in file:list($root) return file:read-text($root || $path)
for $path in file:children('a/b/c') return file:read-text($path)
I have revised the wording in the documentation and added some examples; I hope it’s better understandable now what the functions are supposed to do.
2. The Base vs. Current Working Directory
The concept of the »current working directory« goes back to the early times of the specification of the File Module (which was defined together with guys from Zorba/28msec). There were various reasons why we did not resort to the base URI as default location:
• The static base URI may be empty, and it might point to a non-local resource • If a function of the File Module is located in a library module, we regarded the behavior as counterintuitive if a file function used this module’s URI to resolve local files.
From today’s perspective, I believe it would have been easier to get
rid of the »current working directory« and to exclusively work with the static base URI. In particular, it would have been easier to exchange functions from the File Module and other functions.
In more complex code, it’s usually a good choice to rewrite relative input paths to absolute native paths at the very beginning. The file:path-to-native can be used for that if the addressed path exists. In addition to file:resolve-path, it’s expected to resolve symbolic links and return filenames in their actual case on Windows systems (e.g., “C:\users\” might be rewritten to “C:\Users\”). We didn’t specify the exact behavior in the spec, as it may depend on the operating system. For example, as UNIX-based system works case-sensitive, so there may be two files “a” and “A” in the same directory. And so on.
To answer Hans-Jürgen’s question,
(3) Apparent rule: when called in the GUI, it is - I don't know.
The static base URI is set to a non-existing resource (named "file") in the directory in which an editor file was stored most recently. In earlier versions of BaseX, it was undefined as long as the edited file was not stored. As you can guess, it’s not recommendable to use file:base-dir as long as you don’t know where your query will be stored.