2014-09-02 84 views
5

我有以下個XML:Marklogic查詢

sample1.xml <root> <subjectInfo> <subject id="001"/> <subject id="002" role="cross"/> </subjectInfo> </root>

sample2.xml <root> <subjectInfo> <subject id="002"/> <subject id="001" role="cross"/> </subjectInfo> </root>

我正在尋找的文件,其中值id屬性subject是「001」,但role(如果它存在)相同subject元素不是「交叉」。因此,在我的示例中,結果應該包含sample1.xml,而不是sample2.xml

我想下面的查詢會做的工作:

<code> 
cts:search(/root, 
     cts:near-query((
      cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001"), 
      cts:not-query(cts:element-attribute-value-query(xs:QName("subject"),xs:QName("role"),"cross"))),0) 

      ) 
</code> 

但它不(返回一個空序列)。請給我一個這樣做。

回答

3

正如@wst表示,​​比賽兩份文件。 cts:*查詢匹配文檔片段,而不是子樹。您可以通過嵌套cts:element-query中的cts:element-attribute-value-query構造函數來匹配您的條件的相反情況。這將匹配sample2.xml

cts:search(/root, 
    cts:element-query(xs:QName("subject"), 
    cts:and-query((
     cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001"), 
     cts:element-attribute-value-query(xs:QName("subject"),xs:QName("role"),"cross"))))) 

也許您可以調整您的查詢要求,這就足夠了。如果不是,則可以使用except運算符排除與此搜索匹配的文檔。這將匹配sample1.xml

cts:search(/root, 
    cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001")) 

except 

cts:search(/root, 
    cts:element-query(xs:QName("subject"), 
    cts:and-query((
     cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001"), 
     cts:element-attribute-value-query(xs:QName("subject"),xs:QName("role"),"cross"))))) 

如果你的文檔有唯一的標識符,您可以添加索引範圍和使用的cts:*-values功能之一來獲得的唯一ID匹配第二cts:search文件,然後用​​和cts:*-range-query到排除第一個cts:search的文檔。

+0

非常感謝。這解釋了很多。 – callow 2014-09-03 05:58:29

3

我認爲問題在於​​在兩個文檔上都是匹配的,因此將它們從結果集中排除。

這可能是不夠的,因爲它不是僅索引查詢,但你可以通過過濾誤報出來了補充cts:search結果:

cts:search(/root, 
    cts:element-attribute-value-query(xs:QName("subject"), 
    xs:QName("id"), "001"))[subjectInfo/subject[@id='001' and not(@role='cross')] 
+0

謝謝。這真的很有幫助 – callow 2014-09-03 05:57:12