This exercise is a tutorial in preparing SVG with XQuery, now that you understand how to plot SVG by hand
. We will work with an Assassin's Creed project team file, the game script of Assassin’s Creed Odyssey, which is loaded into the newtfire eXist-dB server, and also available here to right-click and download if needed. In the newtFire eXist-dB server, you may access it by pointing a doc()
variable to
doc('/db/assassinsCreed/assassinscreedodyssey.xml')
We are starting this together in class, and this tutorial is meant to serve as a guide to the various portions of XQuery document you need to prepare. In many respects, writing XQuery to produce SVG is just like writing it to produce HTML. The crucial difference is in the way XQuery handles namespaces. XQuery understands how to work in between HTML and non-namespaced XML documents that most of you have been writing. In writing that code, you did not need to include an HTML namespace: you could simply save your file as HTML, indicate it was to be an HTML document, and the eXist-dB would handle the HTML namespace entry on your output root element for you. However, it requires some special handling to move between SVG and your XML! Without adding an SVG namespace in our XQuery code, we will not be able to view our code in a web browser. Yet as soon as we do that, we need to introduce a special prefix for the qualified name, or Q{}
to permit our XPath to work and reach for data in our source XML files. We will model that here in this exercise.
The Assassin’s Creed team has encoded its script to contain its series of 29 game episodes in an intro
element followed by a series of chapterNum
elements, each wrapping around a set of action
and sp
elements.
action
elements indicate some dynamic game movement or interactivity.sp
element contains a speaker
element inside holding an NPC character name, followed by the text of a speech. For our exercise in plotting SVG, we will start with a pair of questions to investigate:
intro
and chapterNum
elements) compare with each other in terms of relative amount of action? Let’s count up the action in each of those segments and plot it with shapes in SVG. We'll begin by making sure we can access the Assassin's Creed file with XQuery whether we're working in eXist-dB or oXygen. Write XQuery to see if you can output code that loops through the file, using a for loop
to access the sections. (We will start this in class together.) For every one of the 29 segments, see if you can return the count of actions
and the count of distinct-values of speakers
, the data we are seeking. Survey the numbers to get a sense of how large / small they are in relation to each other.
When we are confident we are returning data from the XML file, we turn to plotting SVG. Set up your SVG document like this to balance with the XQuery using curly braces, being sure to include the SVG namespace:
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> <!--We will adjust our "viewport" by altering the width and height attribute values roughly to be larger than the largest X and Y on the plot--> <g> <!--This g can take a transform="translate(x y)" attribute to shift the whole plot over and down as needed-->{
<!--XQuery goes here.-->}
</g> </svg>
Within this new context of SVG namespaced code, we need to insert Q{}
in front of every element name in the XQuery code, like this:
let $acGame := doc('assassinscreedodyssey.xml')
let $intro := $acGame//Q{}
intro
Otherwise, our code will no longer pull data from our source document! Make sure every variable that involves XPath into an element prefixes the Q{}
immediately in front of the element name (no spaces).
Work on outputting data in SVG shapes. To do this using a for loop
, we always add a couple of variables: the $pos
that comes packaged with XQuery for loops and outputs a number for every turn of the loop
as each member of a series is visited in turn. For example, in for $a at $pos in $sections
, the $pos
should return a number counting up for the total number of members in the sequence of $sections
(we expect 29 when we include the intro with the chapterNums). We use the $pos
to help us with plotting across or down (or up) the screen. We also typically set one or more spacer variables that just contain raw numbers to help us multiply by a certain value and give us space we need to plot decorously across or down or up the screen without the shapes or text we're plotting to overlap with one another.
Your goal with this exercise is to use SVG shapes of your choice (lines, rectangles, and/or circles) together with the text element for labeling. Set two shapes side by side or superimpose them to show a relationship between the data of action count vs distinct-speaker count. Label your graph (more than we did in our starter): Make it easy for us to view the numbers associated with each shape, and be sure the section titles appear harmoniously in relationship with the shapes. Learn to work with the $pos
variable moving along with either your x or your y coordinates and spacer variables that you set to make this work!
Revisit the @width
and @height
attributes as you work on this assignment to make them encompass the whole of your plot so that the width is wider than your highest X value, and your height is taller than your largest y value. Consider whether you want to plot across or down or up!
Here is some sample output we produced for this exercise!
If you have saved your files on my newtfire eXist-dB I'll be able to access them there, too, but I'd like you to submit your work on Canvas as you've been doing just to log it there. Copy and paste your XQuery into a file to save with .xql or .xquery file extension. Download and save your output SVG file and submit it if you can as well (but the XQuery by itself is sufficient.)