Search code examples
marklogicmarklogic-8

search xmls which do not have particular element in marklogic


Let's assume I have inserted the below xml in the DB.

<root>
    <name>Dixit</name>
    <entry>
        <vol>1212</vol>
        <title>title1</title>
        <isbn>
            <value>123456</value>
        </isbn>
    </entry>
    <entry>
        <vol>1212</vol>
        <title>title1</title>
    </entry>
</root>

How can I write a cts query which will return me the <entry> nodes with <vol> as 1212 & <title> as title1 & should not have <isbn> element.

For the above xml the output should be.

<entry>
    <vol>1212</vol>
    <title>title1</title>
</entry>

Solution

  • One would normally use cts:not-query(cts:element-query(xs:QName("isbn"), cts:true-query())) to find cases in which the isbn element is missing, but unfortunately the cts:not-query causes the query to look at the entire document, and since your XML document has multiple entries, ones with isbn, and ones without, that will not give the result you hope to see.

    You will either need to post-filter the result from cts:search manually using XPath, for instance like:

    cts:search(
      //entry,
      cts:and-query((
        cts:element-query(xs:QName("vol"), "1212"), 
        cts:element-query(xs:QName("title"), "title1")
      ))
    )[empty(isbn)]
    

    Or split your document to save each entry as a separate document. Then the cts:not-query would work, and give a more convenient solution that scales well too.

    HTH!