XQuery / XPath:如何在使用" |"时从祖先节点检索属性值。运营商?

时间:2015-02-12 08:25:26

标签: xml xpath xquery

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

-file1 / snippet1 -

<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 / snippet2 -

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

两个片段都具有相同的结构。如果我在任何<form type="hyperlemma">内寻找“абиѥ”,则snippet1的路径为$file//entry/form[@type='hyperlemma']/orth(path1),而对于snippet2,则为$file//entry/form/cit/form[@type='hyperlemma']/orth(路径2)。

在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应该存储<entry xml:id="">的属性值。但是我这样做(使用/../../)只返回$file//entry/form[@type='hyperlemma']/orth的属性值。

是否可以将属性值存储在$entry_number中,无论它是path1还是path2?

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

2 个答案:

答案 0 :(得分:2)

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

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-or-self步骤删除了descendant步骤。但请注意,//可能会被XQuery处理器优化(如果可能,请查看生成的查询计划)

答案 1 :(得分:2)

let $entry_number := $path_to_hyperlemma/ancestor::entry[1]/@xml:id

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