3
votes

XML:1

<?xml version="1.0" encoding="UTF-8"?>
<PE uri="/MY/Cases/ILJ/ilj2010_1_00042.xml">
          <P name="antony" value="cse"/>
          <P name="type" value="reported"/>
          <P name="year" value="2010"/>
          <P name="part" value="1"/>
          <P name="volume" value="2"/>
          <P name="decdate-year" value="2010"/>
          <P name="decdate-month" value="01"/>
          <P name="decdate-day" value="27"/>
</PE>

XML:2

<?xml version="1.0" encoding="UTF-8"?>    
<PE uri="/MY/Cases/ILJ/ilj2010_1_00042.xml">
          <P name="antony" value="cse"/>
          <P name="type" value="reported"/>
          <P name="year" value="2010"/>
          <P name="part" value="1"/>
          <P name="volume" value="1"/>
          <P name="decdate-year" value="2010"/>
          <P name="decdate-month" value="01"/>
          <P name="decdate-day" value="27"/>
</PE>

I'm using the below Xquery to differentiate the multiple xml. But I'm not getting the exact output. Here my question is how to filter the element with multiple attributes? I want to get the result for Volume =2 means it should return only the first xml.

MY query

xquery version "1.0-ml";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";

let $value1  := "antony"
let $value2 := "cse"
let $value3  := "year"
let $value4 := "2010"
let $value5  := "volume"
let $value6 := "2"
let $value7  := "part"
let $value8 := "1"

    for  $uri1 in cts:uris((),(), (
          cts:element-query(xs:QName("P"),

            cts:and-query(
            (
cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value1)  ,
cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value2),
cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value3),
cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value4),
cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value5),
cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value6),
cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value7),
cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value8)

))
 )) )

return doc($uri1)
2

2 Answers

1
votes

The best approach is to change the XML representation and manifest the semantics of the model with element or attribute names instead of attribute values, as in:

<pe>
    <type>reported</type>
    <part>1</part>
    <volume>1</volume>
    <date>2010-01-27</date>
</pe>

Then the query becomes something like the following:

cts:element-query(xs:QName("pe"), (
    cts:element-value-query(xs:QName("type"),"reported"),
    cts:element-value-query(xs:QName("part"),"1"),
    cts:element-value-query(xs:QName("volume"),"1"),
    cts:element-value-query(xs:QName("date"),"2010-01-27")
    ))

This approach also lets you create useful range indexes or path range indexes on the values.

Hoping that helps,

0
votes

For each of the name/value attribute pairs, use a cts:element-query() specifying the P element, with a cts:and-query() containing cts:element-attribute-value-query()criteria for both of the attributes for that particular P element.

This will ensure that the criteria has to be met for both attributes on the same P element, rather than just a test to ensure that there is an attribute with that value anywhere within the document.

xquery version "1.0-ml";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";

let $value1  := "antony"
let $value2 := "cse"
let $value3  := "year"
let $value4 := "2010"
let $value5  := "volume"
let $value6 := "2"
let $value7  := "part"
let $value8 := "1"

for  $uri1 in cts:uris((),(), (
      cts:element-query(xs:QName("P"),
        cts:and-query((
         cts:element-query(xs:QName("P"), cts:and-query((
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value1),
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value2)))),
         cts:element-query(xs:QName("P"), cts:and-query((
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value3),
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value4)))),
          cts:element-query(xs:QName("P"), cts:and-query((
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value5), 
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value6)))),
         cts:element-query(xs:QName("P"), cts:and-query((
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("name"),$value7),
            cts:element-attribute-value-query(xs:QName("P"),xs:QName("value"),$value8))))
     )) )) )

return doc($uri1)

cts:element-query()

Searches for matches in the specified element and all of its descendants. If the specified query in the second parameter has any cts:element-attribute-*-query constructors, it will search attributes directly on the specified element and attributes on any descendant elements.