0

Using XPath 2.0 in eXist 4.4 and XQuery.

I have a series of documents in eXist-db directory /db/apps/deheresi/data which I want to retrieve with collection(), but using a wildcard or predicate to filter specifically-named documents.

For example, I'd like to get the documents that begin with ABC and end with .xml. I thought a wildcard like so ?select=ABC*.xml would work, but it's not returning the expected results.

collection("/db/apps/deheresi/data?select=ABC*.xml")

I also tried to apply a combination of starts-with and ends-with but to no success. I am no doubt overlooking something simple here.

Thanks in advance.

jbrehr
  • 775
  • 6
  • 19
  • You will need to tell us which environment you use XPath 2.0 with, the use of the `collection` function is not standardized, I am rather sure Saxon 9 for instance supports your attempt of `collection("file:///db/apps/deheresi/data?select=ABC*.xml")` if `/db/apps/deheresi/data` is the path to a directory but other processors or environments like XML data bases might have very different conventions to use the `collection` function. – Martin Honnen Nov 12 '18 at 15:11
  • Ah, will this is in eXist-db 4.4 and XQuery 3.1. I will update the post accordingly. – jbrehr Nov 12 '18 at 15:14
  • As Martin says, the `select=*.xml` convention is peculiar to Saxon though I believe it has been copied by some other XQuery implementations. But it's not defined in the W3C specs so you can't expect every processor to support it. – Michael Kay Nov 12 '18 at 17:02
  • @MichaelKay Are there other XPATH functions or predicate tricks to filter collections on the document name that I might try? – jbrehr Nov 12 '18 at 17:06
  • You could try using `uri-collection()` which gives you a list of all the URIs, and then filter this yourself before retrieving the documents. But I've no idea if that works, or is the best solution, in the context of eXist-db. – Michael Kay Nov 12 '18 at 17:08

1 Answers1

1

One way of doing this in exist

xquery version "3.1";
(: get document names :)
 let $doc-names := for $n in collection('/db/apps/deheresi/data')
 return
    util:document-name($n)

(: apply filter :)
 for $f in $doc-names[matches(., '^ABC.*\.xml$')]
 return
  $f
duncdrum
  • 723
  • 5
  • 13
  • Indeed, I did something similar...I was just hoping there was a way do to it without a `for`. – jbrehr Nov 12 '18 at 19:01
  • 1
    another way (without for) `xmldb:get-child-resources('/db/apps/deheresi/data')[matches(., '^ABC.*\.xml$')]` – duncdrum Nov 12 '18 at 19:05