NewtFire logo: a mosaic rendering of a firebelly newt
newtFire {dh}
Creative Commons License Last modified: Monday, 28-Mar-2022 03:26:41 UTC. Maintained by: Elisa E. Beshero-Bondar (eeb4 at psu.edu). Powered by firebellies.

XQuery to SVG: Some things to know and access as we begin

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.

Our task

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.

For our exercise in plotting SVG, we will start with a pair of questions to investigate:

XQuery to 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!

Submitting your homework

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.)