Получение имени файла XML-файла с помощью XQuery

Я храню свои объекты в базе данных eXist XML и использую имя файла (идентификатор ресурса) в качестве идентификатора объекта.

Пример:

String xquery = "for $movie in collection('/db/movie')//movie "
    + "return $movie";

После выполнения этого запроса я извлекаю org.xmldb.api.base.Resource экземпляр, содержимое которого я использую для создания объекта. Когда я хочу установить идентификатор этой сущности, я делаю это так:

dvd.setId(rs.getId());

Проблема в том, что если я выполню такой запрос:

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() возвращает null. Я также пробовал метод getDocumentId() из этого класса, но также возвращает null. Есть ли способ заставить его вернуть идентификатор ресурса (который является именем файла, в котором хранится объект)?

Если это невозможно, есть ли способ (функция или что-то еще) получить имя файла, с которым я работаю (я имею в виду, база данных извлекает данные) с помощью запроса XQuery?

Я попытался заменить эту строку:

+ "return <dvd>"

с этим:

+ "return <dvd id=\"{$dvd}\">"

(чтобы я мог получить имя файла из атрибута), но он не возвращает имя файла.


person VaclavDedik    schedule 17.06.2011    source источник


Ответы (3)


Возможно, вы ищете fn:base-uri(). См. здесь.

person morja    schedule 17.06.2011
comment
Спасибо ! Большой. Но если есть что-то, что возвращает только имя файла (а не весь uri), дайте мне знать, пожалуйста. - person VaclavDedik; 17.06.2011
comment
Вы, наверное, могли бы сделать что-нибудь вроде fn:substring-after(fn:base-uri($dvd),fn:static-base-uri()). Или другой замените на fn:replace(). Я не знаю функции, которая делает это напрямую. - person morja; 17.06.2011
comment
Я использую fn: substring (fn: base-uri ($ dvd), 9) (потому что я знаю, что uri всегда имеет одинаковую длину), но спасибо за идею! - person VaclavDedik; 17.06.2011
comment
Я бы предложил вместо этого использовать document-uri( root( $dvd ) ), он возвращает (как описано на этой странице) то же самое, но предотвращает потенциальные проблемы с базовыми атрибутами, когда они присутствуют ... - person DiZzZz; 19.09.2014

Поскольку вы используете eXist-db, вы можете использовать util: document-name () функция:

util:document-name($dvd)
person Joe Wicentowski    schedule 11.03.2013

fn:base-uri вернет весь URI, а не последнюю часть URI, но вы можете использовать решение с регулярным выражением в сочетании с функцией fn:base-uri для решения, которое не зависит от функций, специфичных для eXist.

Это конкретное регулярное выражение обрезает расширение с помощью \. \ W + $ и захватывает имя файла без расширения в группе захвата 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)

В качестве альтернативы для всего файла с расширением

  let $file := replace(fn:base-uri($doc),'^(.*/)(.*?\.\w+$)','$2')
person conteh    schedule 30.06.2016
comment
Да, первый ответ на самом деле не дает метода для получения только имени файла, а скорее всего пути к файлу или uri. На самом деле это не ответ на вопрос. [xqueryfunctions.com/xq/fn_base-uri.html] И второй специфичен для exist-db. Этот работает с basexdb. Я читал это в комментариях. Но если есть что-то, что возвращает только имя файла (а не весь uri), дайте мне знать, пожалуйста, я думал, что это то, о чем просили, а не. - person conteh; 01.07.2016
comment
Я отредактировал ваш ответ, включив в него важные части вашего комментария, потому что он очень полезен для людей, которые просто просматривают ответы. Я видел, как OP принял ответ fn:base-uri, и подумал, что он сделал все, что хотел OP. Теперь я вижу, что комментарии говорят об обратном. Как видите, люди пропускают комментарии. - person Louis; 01.07.2016
comment
return let $file := - недопустимый синтаксис в eXist 2.2, и ваши регулярные выражения не будут работать для файлов без расширения (что вполне возможно). - person Louis; 01.07.2016
comment
Спасибо, Луи, да, я не поместил туда полный код. Я только что поместил частичный код, чтобы в основном отображать регулярное выражение. Код там теперь работает в basex. Он сохраняет коллекцию xml-документов в basex, названную именем файла без расширения. Я не тестировал на existdb, но db: replace - это функция basex, которая, как мне кажется, потребует корректировки на existdb. - person conteh; 01.07.2016