Reputation: 1980
I store my entities in the eXist XML database and I use a file name (resource id) as an ID of an entity.
Example:
String xquery = "for $movie in collection('/db/movie')//movie "
+ "return $movie";
After executing this query I retrieve org.xmldb.api.base.Resource
instance whose content I use to create an entity. When I want to set an id of this entity, I do it like this:
dvd.setId(rs.getId());
The problem is that if I execute query like this:
String xquery = "for $dvd in collection('/db/dvd')//dvd "
+ "return <dvd>"
+ "{$dvd/title}"
+ "{$dvd/type}"
+ "{"
+ "<content>"
+ " {"
+ " for $movie in $dvd/content//movie"
+ " let $movieIn := doc(concat(\"/db/movie/\", $movie/@id))/movie"
+ " return "
+ " <movie id=\"{$movie/@id}\">"
+ " {$movieIn/name}"
+ " {$movieIn/director}"
+ " {$movieIn/year}"
+ " {$movieIn/country}"
+ " {$movieIn/actors}"
+ " {$movieIn/genres}"
+ " </movie>"
+ " }"
+ "</content>"
+ "}"
+ "</dvd>";
rs.getId()
returns null
. I also tried method getDocumentId()
from this class, but it returns null
as well. Is there a way of making it return the id of the resource (which is the name of the file which the entity is stored in) ?
If it's not possible, is there a way (function or something) of getting the file name of the file which I'm working with (I mean, the database retrieves data from) with an XQuery query ?
I tried replacing this line:
+ "return <dvd>"
with this:
+ "return <dvd id=\"{$dvd}\">"
(so that I could get the name of the file from the attribute) but it doesn't return the file name.
Upvotes: 9
Views: 8112
Reputation: 1614
fn:base-uri
will return the whole URI rather than the last part of the URI, but you can use a regex solution combined with the fn:base-uri
function for a solution that is not dependent on eXist-specific functions.
This particular regex trims the extension with \.\w+$ and captures the filename without extension in capture group 2
declare namespace db="http://basex.org/modules/db";
declare namespace file="http://expath.org/ns/file";
declare variable $path as xs:string external;
let $docs := collection($path)
for $doc in $docs
return
let $file := replace(fn:base-uri($doc),'^(.*/)(.*?)\.\w+$','$2')
return db:replace('13F', $file, $doc)
Alternatively for the whole filename with extension
let $file := replace(fn:base-uri($doc),'^(.*/)(.*?\.\w+$)','$2')
Upvotes: 0
Reputation: 5294
Since you're using eXist-db, you can use the util:document-name() function:
util:document-name($dvd)
Upvotes: 13