【问题标题】:Getting filename of an XML file with XQuery使用 XQuery 获取 XML 文件的文件名
【发布时间】:2011-09-17 04:36:51
【问题描述】:

我将我的实体存储在 eXist XML 数据库中,并使用文件名(资源 ID)作为实体的 ID。

例子:

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

执行此查询后,我检索org.xmldb.api.base.Resource 实例,我使用其内容创建实体。当我想设置这个实体的 id 时,我会这样做:

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。我还尝试了来自this class 的方法getDocumentId(),但它也返回null。有没有办法让它返回资源的ID(这是实体存储的文件的名称)?

如果不可能,有没有办法(函数或其他东西)通过 XQuery 查询获取我正在使用的文件的文件名(我的意思是,数据库从中检索数据)?

我尝试替换这一行:

+ "return <dvd>"

用这个:

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

(以便我可以从属性中获取文件名)但它不返回文件名。

【问题讨论】:

    标签: java xquery exist-db


    【解决方案1】:

    由于您使用的是 eXist-db,您可以使用 util:document-name() 函数:

    util:document-name($dvd)
    

    【讨论】:

      【解决方案2】:

      您可能正在寻找fn:base-uri()。见here

      【讨论】:

      • 谢谢!伟大的。但是如果有一些东西只返回文件名(不是整个 uri),请告诉我。
      • 你可以做类似fn:substring-after(fn:base-uri($dvd),fn:static-base-uri())的事情。或者另一个替换为fn:replace()。我不知道直接执行此操作的函数。
      • 我使用 fn:substring(fn:base-uri($dvd), 9) (因为我知道 uri 的长度始终相同)但感谢您的想法!
      • 我建议改用document-uri( root( $dvd ) ),它返回(如该页面上所述)相同,但它可以防止存在时基本属性的潜在问题......
      【解决方案3】:

      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')
      

      【讨论】:

      • 是的,第一个答案实际上并没有提供仅获取文件名的方法,而是获取整个文件路径或 uri。这真的不是在回答问题。 [xqueryfunctions.com/xq/fn_base-uri.html] 第二个是exist-db 特定的。这个适用于basexdb。我在 cmets 中读到了这个“但如果有一些东西只返回文件的名称(不是整个 uri),请告诉我”我认为这是被问到的,但不是。
      • 我已经编辑了您的答案,将您评论的重要部分包含在其中,因为它对于只是扫描答案的人非常有用。我看到 OP 接受了 fn:base-uri 答案,并认为它完成了 OP 想要的一切。我现在看到 cmets 另有说明。如您所见,人们会跳过 cmets。
      • return let $file := 在 eXist 2.2 中是无效语法,并且您的正则表达式不适用于没有扩展名的文件(这很有可能)。
      • 谢谢路易斯,是的,我没有把完整的代码放在那里。我刚刚放了一些部分代码来主要显示正则表达式。那里的代码现在可以在 basex 中使用。它将一组 xml 文档保存在 basex 中,由文件名命名,不带扩展名。我没有在 existsdb 上测试过,但 db:replace 是一个 basex 函数,我相信因此需要在 existsdb 上进行调整。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      相关资源
      最近更新 更多