Part I due by 11:59 p.m. on Tuesday, October 20, 2026.
Part II due by 11:59 p.m. on Tuesday, October 27, 2026.
In your work on this assignment, make sure to abide by the collaboration policies of the course. Unless they are labeled pair-optional, the problems in this assignment are individual-only problems that you must complete on your own.
If you have questions, please come to office hours, post them on
Piazza, or email cs460-staff@cs.bu.edu.
Make sure to submit your work on Gradescope, following the procedures found at the end of Part I and Part II.
30 points total
This part of the assignment asks you to construct XPath and XQuery queries for an XML version of our entire movie database. The schema of this XML database is described here.
Create a subfolder called ps3 within your
cs460 folder, and put all of the files for this assignment in that
folder.
Download the following files into your ps3 folder:
Make sure to put the files in your ps3 folder. If your browser
doesn’t allow you to specify where a file should be saved, try
right-clicking on each link above and choosing Save as... or Save
link as..., which should produce a dialog box that allows you to
choose the correct folder for the file.
We will be using an XML DBMS called BaseX. If you haven’t already installed it, you should do now using the instructions that are available here.
As outlined in our instructions, you can perform queries by taking the following steps:
Start up the BaseX GUI by double-clicking on the JAR file that you downloaded.
Select the Database->New menu option, click the Browse button,
and use the resulting dialog box to find the imdb.xml
file that you downloaded above.
Click Open to select the file, and click OK to create the database.
To execute a query, enter it in the Editor pane in BaseX, and click the green play button to execute it. (You can also use Ctrl+Enter or Ctrl+Return for this purpose.)
The results (if any) will be displayed in the Result pane.
If you have trouble getting BaseX to work on your machine, see the troubleshooting tips on our BaseX page.
If you’re using a Mac, you should disable smart quotes, because they may lead to errors in BaseX and in our testing. There are instructions for doing so here.
ps3_queries.py is a Python file, so you could use a Python IDE
to edit it, but a regular text editor like TextEdit or Notepad++
would also be fine. However, if you use a text editor, you must
ensure that you save it as a plain-text
file.
Construct the XQuery commands needed to solve the problems given below. Test each command in BaseX to make sure that it works.
Once you have finalized the XQuery command for a given problem, copy
the command into your ps3_queries.py file, putting it between
the triple quotes provided for that query’s variable. We have
included a sample query to show you what the format of your
answers should look like.
Each of the problems must be solved by means of a single query. Unless the problem specifies otherwise, you may use either a standalone XPath expression or an XQuery FLWOR expression.
Unless the problem specifies otherwise, you must limit yourself to features of XQuery that we have discussed in lecture. See our general query-writing guidelines for more details.
The only place that you may use a subquery (i.e., a nested FLWOR
expression) is in the results clause of an outer FLWOR
expression. You should NOT have a nested FLWOR expression in a
for clause or a let clause.
Unless a problem specifies otherwise, the order of the clauses
in each query/subquery must follow the FLWOR acronym: a for
clause (F), followed optionally by a let clause (L), followed
optionally by a where clause (W), followed optionally by an
order by clause (O), followed by a return clause (R). You
should not put the clauses in a different order – e.g.,
for, followed by let, followed by another for, etc. BaseX
may allow you to do this, but it is never necessary to do so, and
such a query will often fail to run to completion in the
Autograder.
Your queries should only use information provided in the problem itself. In addition, they should work for any XML database that follows the schema that we have specified.
You do not need to worry about indenting and line breaks in the results of your queries.
3 points
Make sure to read and follow the guidelines given above.
In Problem Set 1, you wrote
a SQL query to find information about all Spider-Man movies and all
Avengers movies. Write a standalone XPath expression (not a
FLWOR expression) to find the full movie elements of these
movies.
Hint: You should use the contains function to perform
substring matching, and you should assume that:
All movies from the Spider-Man franchise have the string
'Spider-Man' (including the hyphen) somewhere in their name.
All movies from the Avengers franchise have the word
'Avengers' somewhere in their name.
3 points
What if you were only looking for the names of the movies from the previous problem?
Your answer for this problem should revise your standalone XPath
expression from the previous problem so that it returns only the
name elements of all Spider-Man movies and all Avengers
movies. For full credit, your query should use the dot operator
(.) to allow the XPath expression to be shorter.
4 points
In our XML movie database, both movie and
person elements include an attribute called oscars if the
corresponding movie or person has received one or more
Oscars. These oscar attributes are of type IDREFS, and they’re
used to capture the relationships between a person or movie and
the corresponding Oscar or Oscars.
For example, here is the beginning of the movie element for the
movie Titanic:
<movie id="M0120338" directors="P0000116"
actors="P0000138 P0000701 P0000708 P0000870 P0000200"
oscars="O19980000000 O19980000116">
<name>Titanic</name>
<year>1997</year>
...
Because that movie won two of the Oscars in our database, it has
an attribute of called oscars whose value is a list containing
two id values for the corresponding oscar elements from
elsewhere in the database.
It’s also worth noting that the id values shown in the oscars
attribute for Titanic each begin with the string "O1998". The
upper-case O indicates that it is an Oscar id, and the 1998
indicates that the Oscars were awarded in 1998. This same format
is used for all Oscar id values in the database: they each begin
with an upper-case O, followed by the year in which the Oscar
was awarded, followed by some additional numeric digits.
Based on the above information, write a standalone XPath
expression (not a FLWOR expression) to find the names of all
people and all movies that won an Oscar this year. You should assume
that the id values of all of the relevant Oscars include the string
"O2026" (an upper-case O, followed by the digits 2026). The
result of the query should be a collection of name elements with the
names of the winning movies and people.
Hints:
Here again, you should use the contains function to perform
substring matching.
The attributes of a given element are considered children of that element in the XML document tree, at the same level as its nested child elements.
Some of the name elements that we’re looking for have a
parent of type movie and others have a parent of type
person. As a result, you should take advantage of the fact
that the .. operator allows you to create an XPath
expression that does not depend on which type of parent an
element has.
4 points
In Problem Set 2, you wrote a SQL query to find information about the movie or movies directed by Joel Coen, Ethan Coen, or both. Write a FLWOR expression to solve this same problem. The results of the query should be pairs of elements:
name child element of one of the moviesdirector whose value is the name
of one of the directors of the movie.If a movie was directed by both of them, it should appear twice in the results.
Sort the results by the year of the movie, and break ties using the name of the director.
Hints:
You will need to use parentheses, commas and curly braces as part
of your return clause. In lecture and lab, we’ve seen
examples of queries that use these delimiters.
When reformatting the results, you will need to use the
string() function to obtain the values of some elements,
without their begin and end tags.
When sorting, you can break ties in the same way that we did in
SQL, by providing additional quantities to sort on.
For example, let’s say that our query was assigning movie
elements to a variable $m and we wanted to sort the results by
the movie’s rating and then by the movies’s runtime. To
do so, we would use the following clause:
order by $m/rating, $m/runtime
4 points
In Problem Set 1, you wrote a SQL query to determine, for each movie rating, the shortest runtime, longest runtime and average runtime of movies with that rating. Write a FLWOR expression to solve a similar problem. As you did in PS 1, should exclude any movie rating that is associated with fewer than 10 of the movies in our database.
The result of the query should be new elements of type rating-stats
that each include the following:
a child element called rating that contains the rating
name; see below for more details about this element
a new child element of type num-movies that has as its
value the number of movies in the database with that rating
a new child element of type shortest that has as its value the
shortest runtime of movies in the database with that rating
a new child element of type longest that has as its value the
longest runtime of movies in the database with that rating
a new child element of type average that has as its value the
average runtime of movies in the database with that rating
For example, here are the results for the PG rating:
<rating-stats> <rating>PG</rating> <num-movies>162</num-movies> <shortest>81</shortest> <longest>216</longest> <average>112.27160493827161</average> </rating-stats>
Hints:
Remember that you do not need to worry about indenting or line breaks in the results of your queries.
To ensure that you only consider a given rating once, you should
use the distinct-values function. For example, to iterate
over distinct Oscar types, you would do the following:
for $t in distinct-values(//oscar/type)
distinct-values gives you the text values of the
corresponding elements, not the elements themselves. As a
result, your return clause will need to construct new rating
elements by adding back in the begin and end tags that were
removed by distinct-values.
You will need to use one or more of the following built-in
aggregate functions: count(), sum(), avg(), min() and
max(). In lecture and lab, we’ve seen examples of
queries that illustrate how to use this type of function.
Some of the hints for the previous problems also apply here.
4 points
Write a FLWOR to summarize the Oscars won by each movie with a G rating, including movies with no Oscars.
The results of the query should be new elements of type
g_movie that include the following nested child elements:
the name child element of one of the G-rated movies in our database
the year child element of that movie
a new element of type num_awards that has as its
value the number of Oscars won by that movie; if the movie
did not win any Oscars, the value of this element should be 0
for each Oscar won by the movie (if any), the type child
element of the corresponding oscar element; sort these
type elements in ascending order.
If the movie did not win any Oscars, the resulting g_movie
element should not have any nested type elements.
For example, here is what the results for the movie My Fair Lady should look like:
<g_movie> <name>My Fair Lady</name> <year>1964</year> <num_awards>3</num_awards> <type>BEST-ACTOR</type> <type>BEST-DIRECTOR</type> <type>BEST-PICTURE</type> </g_movie>
Hints:
You will need to use a subquery (i.e., a nested FLWOR
expression). Remember that these are only allowed in the return
clause of the outer query. In lecture and lab, we’ve
seen examples of queries that illustrate how to use a nested FLWOR
expression to nest an arbitrary number of child elements within
one of the result elements returned by the outer query.
Some of the hints for the previous problems also apply here.
4 points
In Problem Set 1, you
wrote a SQL query to find information about the most recent horror
movie(s) in our database – i.e., the horror movie or movies whose
year is the largest. Write a FLWOR expression to solve a similar
problem – but in addition to finding the name and year of each of
these movies, you should also find its director. If multiple horror
movies are tied for the largest year, your query should retrieve all
of them. As you did in PS 1, you should assume that any horror movie
has the letter 'H' somewhere in the value of its genre
attribute.
The result of the query should be new elements of type
recent_horror that each include the following nested child
elements:
the name and year child elements of one of the most
recent horror movies
a new element of type director that has as its value the name of
the director.
For example, here is one of the result elements:
<recent_horror> <name>Sinners</name> <year>2025</year> <director>Ryan Coogler</director> <actor>Hailee Steinfeld</actor> <actor>Jack O'Connell</actor> <actor>Michael B. Jordan</actor> <actor>Miles Caton</actor> <actor>Wunmi Mosaku</actor> </recent_horror>
You must sort the results in the following ways:
Sort the recent_horror elements in ascending order by
the name of the movie.
Within a given recent_horror element, sort the director child
elements in ascending order by name, and the actor child
elements in ascending order by name.
Hints and guidelines:
Important: For the sake of efficiency, your outer query
should have a let clause that comes before its for
clause. This will allow you to compute one or more key values once
and assign them to variables, so that these variable(s) can be
used throughout the execution of the for clause.
You will need to use two different subqueries: one to obtain the movie’s directors, and one to obtain its actors. When doing so, you should put a comma between the two nested FLWOR expressions.
Some of the hints for the previous problems also apply here.
4 points
In Problem Set 2, you wrote a SQL query to find information about times in which two people shared a given type of Oscar. Write a FLWOR expression to find all examples of this in our database.
The result of the query should be new elements of type
shared_oscar that each include the following nested child
elements:
one called year for the year in which the Oscar was shared
one called type for the type of the shared Oscar
for each person who shared the Oscar, a new element
of type winner that has as its value the name of the person
and the name of the corresponding movie, separated by a hyphen.
For example:
<shared_oscar> <year>1969</year> <type>BEST-ACTRESS</type> <winner>Barbra Streisand - Funny Girl</winner> <winner>Katharine Hepburn - The Lion in Winter</winner> </shared_oscar>
You must sort the results in the following ways:
Sort the shared_oscar elements in descending order by year; see
below for info about how to do this. If there is more than one
shared_oscar in a given year, sort them in ascending order by
type.
Within a given shared_oscar element, sort the winner
child elements in ascending order by the name of the person.
Hints:
You will need to use the distinct-values function twice:
once to obtain possible Oscar years, and once to obtain possible
Oscar types.
Remember that distinct-values gives you the text values of the
corresponding elements, not the elements themselves, so you should
add back begin and end tags as needed.
In XQuery, when you ask it to sort the results, it puts them
in ascending/increasing order by default. To obtain
descending/decreasing order, put the word descending after
the thing that you are sorting on.
Some of the hints for the previous problems also apply here.
Coming soon
70 points total
Last updated on October 4, 2026.