【问题标题】:XQuery / XPath: How to retrieve an attribute value from an ancestor node when using "|" operator?XQuery / XPath:使用“|”时如何从祖先节点检索属性值操作员?
【发布时间】:2015-02-12 08:25:25
【问题描述】:

我正在将一个 XQuery 文件应用于两个 XML 文件:

-file1/sn-p1-

<entry xml:id="SCHOM-2">
    <form type="hyperlemma" xml:lang="cu">
        <orth>абиѥ</orth>
    </form>
    <form type="lemma" xml:lang="cu">
        <orth>абиѥ</orth>
        <cit type="counterpart" xml:lang="grc">
            <form type="hyperlemma" xml:lang="grc">
                <orth>παραχρῆμα</orth>
            </form>
            <form type="lemma" xml:lang="grc">
                <orth>παραχρῆμα</orth>
            </form>
        </cit>
    </form>
</entry>

和 -file2/sn-p2-

<entry xml:id="arg-3150">
    <form type="hyperlemma" xml:lang="grc">
        <orth>ἐξαυτῆς</orth>
    </form>
    <form type="lemma" xml:lang="grc">
        <orth>ἐξαυτῆς</orth>
        <cit type="translation" xml:lang="cu">
            <form type="hyperlemma" xml:lang="cu">
                <orth>абиѥ</orth>
            </form>
            <form type="lemma" xml:lang="cu">
                <orth>абие</orth>
            </form>
        </cit>
    </form>
</entry>

两个 sn-ps 具有相同的结构。如果我在任何 &lt;form type="hyperlemma"&gt; 中查找“абиѥ”,则 sn-p1 的路径是 $file//entry/form[@type='hyperlemma']/orth (path1),而 sn-p2 是 $file//entry/form/cit/form[@type='hyperlemma']/orth (path2)。

在 XQuery 文件中,我有以下 FLWOR 表达式:

xquery version "3.0";
...
for $file in collection($collection_path),
    $path_to_hyperlemma in $file//(entry | cit)/form[@type='hyperlemma']/orth [ft:query(., $searchphrase)]
let $entry_number := $path_to_hyperlemma/../../@xml:id
return
....

$entry_number 应该存储&lt;entry xml:id=""&gt; 的属性值。但是我这样做的方式(使用/../../)当然只返回$file//entry/form[@type='hyperlemma']/orth 的属性值。

是否可以将属性值存储在$entry_number中,不管是path1还是path2?

另一个问题:我知道使用// 在性能方面并不理想。但是如果我用绝对路径替换//,我似乎无法引用不同级别的节点集。在这种情况下是否可以设置绝对路径?

【问题讨论】:

  • 这里不是很清楚问题出在哪里,你能展示一个你正在查询的 XML 的小样本吗?
  • @IanRoberts:我添加了两个 XML sn-ps 并重新表述了我的问题。我希望它现在变得更加清晰......

标签: xml xpath xquery


【解决方案1】:

以下重写可能会有所帮助:

for $file in collection($collection_path),
    $path_to_hyperlemma in $file/(descendant::entry | descendant::cit)/
       form[@type='hyperlemma']/orth[ft:query(., $searchphrase)]
let $entry_number := $path_to_hyperlemma/ancestor::*/@xml:id
return ...
  • xml:id 属性已为所有祖先解析。这仅适用于只有一个具有此类属性的祖先。如果可能还有更多,您需要使用其中一个来选择(例如使用[position() = 1][position() = last()]),或者在您对文档结构的问题中给我们一些说明。

  • 已通过在括号中使用 descendant 步骤删除了 descendant-or-self 步骤。但是,请注意// 可能会被 XQuery 处理器优化(如果可能,请查看生成的查询计划)

【讨论】:

  • 太棒了!您的两个建议都非常有效。非常感谢您抽出宝贵时间提供帮助!
【解决方案2】:
let $entry_number := $path_to_hyperlemma/ancestor::entry[1]/@xml:id

将在树中查找名为 entry 的最近祖先元素的 xml:id

【讨论】:

  • 完美运行!感谢您再次查看我的问题。
猜你喜欢
  • 2020-01-09
  • 1970-01-01
  • 2011-11-10
  • 2011-05-30
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
相关资源
最近更新 更多