Reputation: 817
I am a beginner in Xquery and I have an xml code in which I want to dependent two different XML file with another file.
Book.xml
<library>
<Book>
<title>Title1</title>
<author>Ellizabith</author>
</Book>
<Book>
<title>Title2</title>
<author>Sam</author>
</Book>
<Book>
<title>Title3</title>
<author>Ryan</author>
</Book>
</library>
author.xml
<authorRoot>
<author>
<Name>Rayan</Name>
<Location>Yahoo</Location>
</author>
<author>
<Name>Syan</Name>
<Location>Google</Location>
</author>
<author>
<Name>Sam</Name>
<Location>Bing</Location>
</author>
</authorRoot>
in this answer a query to show the location of all the authors of book whose title contains the word "Title2".
This is my code :
for $p in doc("C:\Users\User\Desktop\Book.xml")//library/book/[title/contains(., 'Title1')]
for $a in doc("C:\Users\User\Desktop\author.xml")//authorRoot
let $p := $p/author/text()
let $d := $a/author
let $f := $d/text()=$p/Location/text()
return $f
Upvotes: 2
Views: 155
Reputation: 38702
There are multiple smaller problems with your codes.
book
in line one).<Book/>
uses a capital B, so do the same in your XQuery, again in line 1.<authorRoot/>
elements. Use authorRoot/author
instead.$p
with it's name for the rest of this FLWOR expression, but you want to use the book again in line five. Better use another variable name.descendant-or-self
-step //
if you don't need it (lines one and two). This decreases performance.I don't get what your idea for filtering was in lines three to five. Compare yourself with this working solution. Additionally I used speaking variable names, don't confuse yourself with unnecessary short ones.
Replace $book
and $authors
by the respecting doc(...)
functions.
for $book in $books//library/Book[title/contains(., 'Title1')]
for $author in $authors//authorRoot/author
where $book/author = $author/Name
return $author/Location/text()
If you want to have a list of distinct places, wrap distinct-values(...)
around all four lines.
An alternative without explicit loops:
$authors/authorRoot/author[
Name = $books/library/Book[contains(title, 'Title1')]/author)
]/Location
The second solution is also valid XPath 1.0, the first requires an XPath 3.0 or XQuery processor.
Upvotes: 3
Reputation: 167676
If you use
let $books := <library>
<Book>
<title>Title1</title>
<author>Ellizabith</author>
</Book>
<Book>
<title>Title2</title>
<author>Sam</author>
</Book>
<Book>
<title>Title3</title>
<author>Ryan</author>
</Book>
</library>
let $authors := <authorRoot>
<author>
<Name>Rayan</Name>
<Location>Yahoo</Location>
</author>
<author>
<Name>Syan</Name>
<Location>Google</Location>
</author>
<author>
<Name>Sam</Name>
<Location>Bing</Location>
</author>
<author>
<Name>Ellizabith</Name>
<Location>Apple</Location>
</author>
</authorRoot>
return $authors/author[Name = $books/Book[contains(title, 'Title1')]/author]/Location/string()
the result is Apple
.
Upvotes: 2