2014-09-02 86 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