11

XML File

<Cities>
  <Place>
    <City n="New Delhi"></City>
    <City n="Chandigarh"></City>
    <City n="Mumbai"></City>
  </Place>
  <Place>
    <City n="New Delhi"></City>
    <City n="Chandigarh"></City>
  </Place>
  <Place>
    <City n="New Delhi"></City>
    <City n="Mumbai"></City>
  </Place>
</Cities>

I am using following XQuery -

for $x in doc("sample")/Cities/Place/City
   order by $x/@n
   return distinct-values($x/@n)

The result I am expecting is - Chandigarh Mumbai New Delhi

but getting - Chandigarh Chandigarh Mumbai Mumbai New Delhi New Delhi New Delhi

Please tell me where am I going wrong?

5 Answers5

14

pls try this -

for $x in distinct-values(doc("sample")/Cities/Place/City/@n)
   order by $x
   return $x

I have checked the same with baseX 7.1 and working smoothly as expected by you :)

John
  • 2,820
  • 3
  • 30
  • 50
6

You are now calling distinct-values on each of the values separately. distinct-values returns the distinct values in a sequence but the sequence now only consists of one element. You should call distinct-values(...) where ... is the sequence of city names.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
0

The distinct-values function

let $items := (1,2,4,4,5,5,9,9,9,9,3,3,2)
let $unique-items-by := distinct-values($items)
return
   <result>   

      <items>
      {
         for $item in $unique-items-by
         return <item>{$item}</item>
      }
      </items>

   </result>
M.Ganji
  • 818
  • 8
  • 13
0

The distinct-values function is used
unique-items

 let  $x:=doc("/db/my.xml")
let $unique-items := distinct-values($x)
 for $x in $unique-items

return (
 $unique-items
)
M.Ganji
  • 818
  • 8
  • 13
0

If you want to be able to still retain the structure of the data though, chat gpt came up with this solution that is interesting. It uses preceding::user instead of distinct-values

xquery version "1.0-ml";

declare namespace user = "http://example.com/user";

declare variable $users := 
<users>
  <user>
    <id>1</id>
    <email>user1@example.com</email>
  </user>
  <user>
    <id>2</id>
    <email>user2@example.com</email>
  </user>
  <user>
    <id>3</id>
    <email>user3@example.com</email>
  </user>
  <user>
    <id>1</id>
    <email>user1@example.com</email>
  </user>
  <user>
    <id>4</id>
    <email>user4@example.com</email>
  </user>
</users>;

for $user in $users/user[not(. = preceding::user)]
let $id := $user/id/text()
let $email := $user/email/text()
return 
  <user>
    <id>{$id}</id>
    <email>{$email}</email>
  </user>
Chase Lundell
  • 93
  • 1
  • 11