Reputation: 87
I have a movie database and want to search for actors with last and/or first name. The goal is to get as list the actors name and the title as well as the role name the actor played in the movie.
The XML movie database looks like this:
<movies>
<movie>
<title>A History of Violence</title>
<year>2005</year>
<country>USA</country>
<genre>Crime</genre>
<summary>Tom Stall, a humble family man and owner of a
popular neighborhood restaurant, lives a quiet but
fulfilling existence in the Midwest. One night Tom
foils a crime at his place of business and, to his
chagrin, is plastered all over the news for his
heroics. Following this, mysterious people follow
the Stalls' every move, concerning Tom more than
anyone else. As this situation is confronted, more
lurks out over where all these occurrences have
stemmed from compromising his marriage, family
relationship and the main characters' former
relations in the process.</summary>
<director>
<last_name>Cronenberg</last_name>
<first_name>David</first_name>
<birth_date>1943</birth_date>
</director>
<actor>
<first_name>Vigo</first_name>
<last_name>Mortensen</last_name>
<birth_date>1958</birth_date>
<role>Tom Stall</role>
</actor>
<actor>
<first_name>Maria</first_name>
<last_name>Bello</last_name>
<birth_date>1967</birth_date>
<role>Eddie Stall</role>
</actor>
<actor>
<first_name>Ed</first_name>
<last_name>Harris</last_name>
<birth_date>1950</birth_date>
<role>Carl Fogarty</role>
</actor>
<actor>
<first_name>William</first_name>
<last_name>Hurt</last_name>
<birth_date>1950</birth_date>
<role>Richie Cusack</role>
</actor>
</movie>
Actually I have the following code and it works so far but for example for the query with last_name=Dunst I get as result:
1. Dunst, Kirsten
movie title as role
2. Dunst, Kirsten
movie title as role
but I want to have the actor just one time so I tried to add distinct-values() but it doesn´t work :( I would like to have the output like this:
1. Dunst, Kirsten
movie title as role
movie title as role
Here is the code:
xquery version "3.0";
declare option exist:serialize "method=xhtml media-type=text/html indent=yes";
let $last_name := distinct-values(request:get-parameter('last_name', ''))
let $first_name := distinct-values(request:get-parameter('first_name', ''))
let $movies := collection('/db/Movie/data')/movies/movie/actor[if(not($last_name)) then xs:boolean(1) else equals(last_name, $last_name)][if(not($first_name)) then xs:boolean(1) else equals(first_name, $first_name)]
return
<html>
<head>
</head>
<body>
<h1>Search results for actor {$last_name} {$first_name}:</h1>
<ol>{
for $movie in $movies
let $title := $movie/../title/text()
let $role := $movie/role/text()
return
<li>{$movie/last_name/text()}, {$movie/first_name/text()} <p> In the movie <i>{$title}</i> as role <i>{$role}</i> </p></li>
}</ol>
</body>
</html>
Hope someone can help me ;) Thanks in advance!
Upvotes: 1
Views: 553
Reputation: 3056
The variable $movies
is bound to a sequence of actor
elements, which causes some confusion.
If you only intend to use this for one actor at a time, you can simply put the actor's name prior to the FLWOR expression, and get your intended output:
<ol>
<li>
<p>{ $movies[1]/last_name }, { $movies[1]/first_name}</p>
{
for $movie in $movies
let $title := $movie/../title
let $role := $movie/role
return
<p>In the movie <i>{$title}</i> as role <i>{$role}</i></p>
}</li>
</ol>
Note: the text()
path selector is unnecessary in this case, and occasionally confusing as it can return a sequence of text nodes. If you need to ensure a type constraint, consider using fn:string()
instead.
Upvotes: 1