CrazyNerd
CrazyNerd

Reputation: 63

Marklogic Element Query

I am trying to write a Xquery to search an xml from the database which has any Abc node having R="3" and it should have any corresponding XYZ node which has attr="106"

    <Abc ID="X" Src="D" R="1">
         <XYZ ID="4101847" attr="106">
         </XYZ>
         <XYZ ID="Y" attr="105">
         </XYZ>
    </Abc>
    <Abc ID="Z" Src="G" R="73">
    </Abc>
    <Abc ID="P" Src="B" R="3">
         <XYZ ID="Q" attr="106">
         </XYZ>
         <XYZ ID="R" attr="101">
         </XYZ>
         <XYZ ID="" attr="100">
         </XYZ>
    </Abc>

I tried below query

cts:element-query(
    fn:QName("namespace","Parent"), cts:and-query(
          (
               cts:element-attribute-value-
query(fn:QName("namespace","Abc"),xs:QName("R"),"3"),
               cts:element-attribute-value-
query(fn:QName("namespace","XYZ"),xs:QName("attr"),"106")

        )   
        ) 
)

It gives me result even if any other Abc has an XYZ node matching attr as 106

Upvotes: 0

Views: 110

Answers (2)

grtjn
grtjn

Reputation: 20414

You want to constrain both attribute value queries to the same Abc parent element. You need to do a cts:element-query on Abc to achieve that. Doing the element-query on the parent of Abc would be too high. Below some code to illustrate things more clearly. Note that I saved your Abc examples as separate files for best understanding:

xquery version "1.0-ml";

xdmp:document-insert("/abc1.xml",
  <Abc ID="X" Src="D" R="1">
         <XYZ ID="4101847" attr="106">
         </XYZ>
         <XYZ ID="Y" attr="105">
         </XYZ>
    </Abc>
),
xdmp:document-insert("/abc2.xml",
    <Abc ID="Z" Src="G" R="73">
    </Abc>
),
xdmp:document-insert("/abc3.xml",
    <Abc ID="P" Src="B" R="3">
         <XYZ ID="Q" attr="106">
         </XYZ>
         <XYZ ID="R" attr="101">
         </XYZ>
         <XYZ ID="" attr="100">
         </XYZ>
    </Abc>
)

;

cts:search(collection(), cts:element-query(
  xs:QName("Abc"),
  cts:and-query((
    cts:element-attribute-value-query(
      xs:QName("Abc"),
      xs:QName("R"),
      "3"
    ),
    cts:element-attribute-value-query(
      xs:QName("XYZ"),
      xs:QName("attr"),
      "106"
    )
  ))
))

HTH!

Upvotes: 0

You should start the query with a scope on the element using cts:element-query()

Upvotes: 1

Related Questions