2014-09-02 26 views
5

Mam następujące plików XML:Marklogic kwerendy na podstawie wartości wielu atrybutów tego samego pierwiastka

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>

szukam dokumentów, w których wartość atrybutu idsubject to "001", ale role (jeśli jest) tego samego elementu subject nie jest "krzyżykiem". Tak, w moim przykładzie wynik powinien zawierać sample1.xml i nie sample2.xml

Myślałem następujące zapytanie będzie wykonać zadanie:

<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> 

Ale to nie (zwraca pusty ciąg). Proszę, daj mi taki, który to robi.

Odpowiedz

3

Jak @wst powiedziawszy, cts:not-query meczów obu dokumentów. cts:* zapytania dopasowują fragmenty dokumentu, a nie poddrzew. Możesz dopasować przeciwieństwo swoich warunków, zagnieżdżając konstruktorów cts:element-attribute-value-query wewnątrz cts:element-query. To pasuje 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"))))) 

Być może można dostosować swoje wymagania zapytań więc jest to wystarczające. Jeśli nie, możesz wykluczyć dokumenty pasujące do tego wyszukiwania, używając operatora except. To pasuje 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"))))) 

Jeśli dokumenty mają unikalne identyfikatory, można dodać wskaźniki zasięgu i używać jednej z funkcji cts:*-values aby uzyskać unikalne identyfikatory dla dokumentów pasujących drugą cts:search, a następnie użyj cts:not-query i cts:*-range-query do wyklucz dokumenty z pierwszego numeru cts:search.

+0

Dziękuję bardzo. To dość wyjaśnia. – callow

3

Myślę, że problem polega na tym, że cts:not-query pasuje do obu dokumentów, a zatem wyklucza je z zestawu wyników.

To może nie być wystarczające, ponieważ nie jest to zapytanie indeksu tylko, ale można uzupełnić cts:search wyników przez filtrowanie fałszywych alarmów:

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

Dzięki. To naprawdę pomaga – callow

Powiązane problemy