patricia
patricia

Reputation: 1103

Can't iterate over the elements on and xml file with xquery

I 've got a xml file with this structure:

<profiles>
    <profile profile="SuperAdministrator" name="admin"/>
    <profile project="TesteHandSpy" profile="Researcher" name="john"/>
    <profile project="DunnProject,DAAR1_op,Sara" profile="Researcher" name="juliete"/>
</profiles>

And I want to select the project value of profile elements with a certain value for attribute name. I started trying to just list all profile elements and I'm having problems with that. I can find the file but then I use the comands I find in several places and it returns zero results. Here's the xquery I'm testing:

let $param := "juliete"
let $profiles:= doc("/db/db_project/profiles.xml")/profiles/profile

for $profile in $profiles
return $profile

Can you help me? I guess when this starts to work all I have to do is add [@name=$param] to the query.

Upvotes: 0

Views: 446

Answers (1)

Florent Georges
Florent Georges

Reputation: 2327

There is no need for a FLOWR expression here. A simple path would do:

doc("/db/db_project/profiles.xml")/profiles/profile[@name eq $param]

The fact that this return nothing can be for several reasons. The most obvious are 1) the URI is not correct (try calling doc() with the same URI to ensure it returns the document) or 2) a namespace problem (you can try *:profiles/*:profile to validate that is not the case).

The problem with using doc() is that it is not reproducible on someone else's machine. If you put the content of the document in, say, a variable instead, the query will be self-contained and we will be able to help better.

Update

After your comment, it seems it is a namespace problem. So the XML input you quoted above is not entirely correct. It lacks some namespace, something like:

<profiles xmlns="http://example.org/project">
   ...
</profiles>

A path like /profiles/profile returns the elements profile, children of the element profiles, all in NO namespace. To access those in a specific namespace, you have to bind a prefix to that namespace URI first, and then use the prefix for each element name:

declare namespace p = "http://example.org/project";
doc("/db/db_project/profiles.xml")/p:profiles/p:profile[@name eq $param]

You have to understand that the prefix used in the query (in this case p) and the one used in the XML (in this case no prefix, because the URI is bound as the default namespace) do not have to match. The URIs they are both bound to have to match.

Upvotes: 1

Related Questions