2015-02-12 71 views
0

我申请的XQuery文件,两个XML文件:XQuery/XPath:如何使用“|”从祖先节点检索属性值运营商?

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

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

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

+0

问题的症结并不十分清楚,您能否显示一小部分您正在查询的XML样本? – 2015-02-12 09:19:44

+0

@IanRoberts:我添加了两个XML片段并重新表述了我的问题。我希望现在越来越清晰了...... – smo 2015-02-12 11:54:00

回答

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步骤,descendant-or-self步骤已被删除。但是,请注意,//可以通过XQuery处理器反正进行优化(如果可能的话,请查看生成的查询计划)

+0

太棒了!你的两个建议都能完美工作。非常感谢您花时间帮助! – smo 2015-02-12 16:47:54

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

会抬头看树命名为entry最近的祖先元素的xml:id

+0

它完美的作品!感谢您再次看看我的问题。 – smo 2015-02-12 16:45:34