XQuery - Why does for $x in //loan differ from for $x in //loans and using $x/loan?

StackOverflow https://stackoverflow.com/questions/22737068

  •  23-06-2023
  •  | 
  •  

質問

I have a xml file.

<?xml version = "1.0" encoding = "UTF -8"?>
<library>
<books>
    <book>
        <title>The story of My Life</title>
        <accessionNumber val = "1"/>
    </book>
    <book>
        <title>The Parody</title>
        <accessionNumber val = "2"/>
    </book>
    <book>
        <title>The Automata Theory</title>
        <accessionNumber val = "3"/>
    </book>
</books>
<loans>
    <loan book="1" user="35" dueDate="2006-April-10-05:00"/>
    <loan book="2" user="36" dueDate="2015-May-10-05:00"/>
    <loan book="3" user="36" dueDate="2014-November-10-05:00"/>
</loans>
<users>
    <user> <name> Fred Jones</name> <id val = "35"/> </user>
    <user> <name> Aadeem Nus</name> <id val = "36"/> </user>
</users>

I have to find (a) list of all the loans, sorted by user name

(b) users borrowed more than one book

My solution for (a) I have solved. Solved xquery is:

for $u in doc("lib.xml")//user
for $l in doc("lib.xml")//loan
where $l/@user = $u/id/@val 
order by $u/name
return $u/name

But it took a long because I was trying with

for $u in doc("lib.xml")//users
for $l in doc("lib.xml")//loans
where $l/loan/@user = $u/user/id/@val 
order by $u/user/name
return $u/user/name

I see no difference between them. What is the difference?

(b) Same problem like (a). I solved after a long time. Solved one:

for $u_n in doc("lib.xml")//user 
for $x at $xPos in doc("lib.xml")//loan
for $y at $yPos in doc("lib.xml")//loan
where $x/@user = $y/@user
and $xPos < $yPos
and $u_n/id/@val = $x/@user
return data($u_n/name)

And the unsolved one (which is same as solved one according to me):

for $u_n in doc("lib.xml")//user 
for $x at $xPos in doc("lib.xml")//loans
for $y at $yPos in doc("lib.xml")//loans
where $x/loan/@user = $y/loan/@user
and $xPos < $yPos
and $u_n/id/@val = $x/loan/@user
return data($u_n/name)

Can anyone please give explanation?

Thanks.

役に立ちましたか?

解決

The reason for a difference between

for $u in doc("lib.xml")//user
for $l in doc("lib.xml")//loan
where $l/@user = $u/id/@val 
order by $u/name
return $u/name

and

for $u in doc("lib.xml")//users
for $l in doc("lib.xml")//loans
where $l/loan/@user = $u/user/id/@val 
order by $u/user/name
return $u/user/name

...is that only the former iterates over individual user elements. The second "iterates" over users elements, of which there are only one, so no actual iteration occurs at all.

When you let $l point at loans and use $l/loan/@user, you're asking if any loan at all contains a match -- without looking with any specificity at which loan matched, because $l doesn't point to a single loan! Consequently, your return expression has no way of addressing the specific match, because its $l doesn't look at an individual matched loan, but at their joint parent, loans.


Similarly, for $x at $xPos in doc("lib.xml")//loans only finds one loans element; it doesn't look at the loan elements inside of it, because you aren't telling it to do so.

If you wanted $x to be a loan element, not a loans element, you'd need to either fix it the way you already did, or do this:

for $x at $xPos in doc("lib.xml")//loans/*
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top