我有以下xmls:
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
的{{1}}属性值为“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>
但它没有(返回一个空序列)。请给我一个。
答案 0 :(得分:4)
正如@wst所说,cts:not-query
匹配这两个文件。 cts:*
个查询匹配文档片段,而不是子树。您可以通过将cts:element-attribute-value-query
构造函数嵌套在cts:element-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
函数来获取与第二个cts:search
匹配的文档的唯一ID,然后使用cts:not-query
并cts:*-range-query
从第一个cts:search
中排除文档。
答案 1 :(得分:3)
我认为问题是cts:not-query
在两个文档上都匹配,因此将它们从结果集中排除。
这可能还不够,因为它不是仅索引查询,但您可以通过过滤误报来补充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')]