我正在寻找一个好的解决方案(简短的表达式,最好的性能)来获得所有祖先节点在basex上的xquery 3.1的相反顺序。
现在我使用这段代码,为给定的xml示例获取dira/dira3/dira31:

xquery version "3.1" encoding "utf-8";

declare variable $files :=
  <dir name="dirA">
    <file name="fileA_F1"/>
    <file name="fileA_F2"/>
    <dir name="dirA1">
      <file name="fileA1_F1"/>
      <file name="fileA1_F2"/>
    </dir>
    <dir name="dirA2">
      <file name="fileA2_F1"/>
      <file name="fileA2_F2"/>
    </dir>
    <dir name="dirA3">
      <file name="fileA3_F1"/>
      <file name="fileA3_F2"/>
      <file name="fileA3_F3"/>
       <dir name="dirA31">
        <file name="fileA31_F1"/>
        <file name="fileA31_F2"/>
        <file name="fileA31_F3"/>
      </dir>
    </dir>
  </dir>;


let $path := trace(string-join($files//file[@name='fileA31_F2']/ancestor::dir/@name,'/'))

return()

这个代码得到了相反的顺序dira31/dira3/dira:
let $reversepath := trace(string-join(reverse(tokenize(string-join($files//file[@name='fileA31_F2']/ancestor::dir/@name,'/'),'/')),'/'))

我的意思是,是否还有其他xpath或xquery表达式以相反的顺序遍历祖先?
注释:文件节点的名称属性值是唯一的

最佳答案

另一个建议是:

declare function f:reverse-path($n as node()) {
  if (exists($n/../@name))
  then $n || '/' || f:reverse-path($n/..)
  else @name
};
f:reverse-path($files//file[@name='fileA31_F2'])

或者更一般地说,您需要一个按相反顺序遍历祖先的函数(最里面的祖先优先):
declare function f:reverse-ancestors($n as node()) {
  $n ! (., ..!f:reverse-ancestors(.))
};

10-08 20:00