2014-09-02 4 views
5

Ich habe folgende xmls:Marklogic Abfrage basierend auf den Werten von mehreren Attributen des gleichen Elements

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>

ich für die Dokumente bin auf der Suche, wo Wert von id Attribut von subject ist "001" aber role (wenn es da ist) der gleichen subject Element ist nicht "Cross" .So, in meinem Beispiel sollte das Ergebnisenthaltenund nicht sample2.xml

Ich dachte, die folgende Abfrage die Arbeit machen würde:

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

Aber es funktioniert nicht (gibt eine leere Sequenz). Bitte gib mir eines, das tut.

Antwort

3

Wie @wst sagte, die cts:not-query Streichhölzer beiden Dokumente. cts:* Abfragen stimmen mit Dokumentfragmenten überein, keine Teilbäume. Sie können das Gegenteil Ihrer Bedingungen abgleichen, indem Sie die cts:element-attribute-value-query Konstruktoren in einem cts:element-query verschachteln. Dies wird sample2.xml entsprechen:

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

Vielleicht können Sie Ihre Anfrage Anforderungen anpassen, so dies ausreichend ist. Wenn nicht, können Sie die Dokumente, die dieser Suche entsprechen, mit dem Operator except ausschließen. Dies wird sample1.xml entsprechen:

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

Wenn Ihre Dokumente haben eindeutige Kennungen, könnten Sie Bereich Indizes hinzufügen und eine der cts:*-values Funktionen verwenden, um die eindeutigen IDs für Dokumente zu erhalten, die zweite cts:search passend, und dann cts:not-query und cts:*-range-query verwenden, um schließen Sie die Dokumente von der ersten cts:search aus.

+0

Vielen Dank. Das erklärt ziemlich viel. – callow

3

Ich denke, das Problem ist, dass die cts:not-query auf beide Dokumente übereinstimmt und daher aus der Ergebnismenge ausschließt.

kann dies nicht ausreichend, da es kein Index-only-Abfrage ist, aber man kann die cts:search Ergebnisse durch Ausfiltern Fehlalarme ergänzen:

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

Danke. Das hilft wirklich – callow