Recipe 2: List all works in CroALaBib

Once the CroALaBib XML database is created, we can start analysing it. The bibliographic records are organised along FRBR lines, meaning that every work, every Croatian Latin text in its ideal state, can have multiple manifestations (printed, handwritten, digital, or, in the case of plays, performed; a work can also be translated into another language, or from another language; it can exist in several versions, too).

CroALaBib also collects data on authors, their addressees and sponsors. More about it later, however. We will start from works.

A work can be simple — such that it cannot be subdivided into independent units (an epic poem is made up of cantos, but a single canto is not an autonomous work) — or composite (a collection of poems in which each poem can also stand on its own, or a collection of letters making up somebody's correspondence). Borderline cases are also possible: a cycle of poems, an exchange of verse epistles.

Our first task is to produce a list of all works. As CroALaBib is constantly changing (hopefully for the better), with new records being added, old ones corrected or more deeply encoded, we do not want to produce a fixed list or index. We need a way to report on the most current state of the database.

This is why we will use a XQuery script — an expression which will query the database each time a HTML page is called up through an HTTP request, and respond by displaying results as a table on that page. BaseX supports RestXQ framework, designed for such purposes.

What we need

Location of works in CroALa

TEI XML provides three ways to record bibliographic references. CroALaBib uses two: bibl and biblStruct. bibl and biblStruct records of works are gathered in a listBibl element with a specific value of @ana attribute. This attribute contains string croala.opera (but can also contain other keywords, usually following the dot). Each bibliographic reference has a unique @xml:id attribute.

Composite works are themselves an entity, with their own @xml:id, but they also contain subordinated individual works (which also have specific @xml:id values). We want to find and list both the composite work and all works it consists of.

The XQuery

XQuery language uses XPath to find all elements with certain properties at certain places. For works in CroALa, the basic XPath expression is this:


collection("croalabib")//*:listBibl[matches(@ana,'croala.opera')]//(*:bibl|*:biblStruct)[@xml:id]

Note the double slash (//) which tells the engine to find elements at any level — directly below the previous element, as its "children", or deeper down the XML tree, as "ancestors".

Using this XPath expression, we write a FLOWR XQuery command. If you have recreated the CroALaBib database on your computer, you can copy the script from here, paste it into an Editor window of the BaseX GUI, and run it — see what you will get. (You can also change parameters and see what happens.)


for $opus in collection("croalabib")//*:listBibl[matches(@ana,'croala.opera')]//(*:bibl|*:biblStruct)[@xml:id]
  order by $opus/*:author[1] collation "?lang=hr"
  return element tr {
    element td { $opus/@xml:id) }
  }

We have decided to order the list (at first) by first letters of names of first authors in each record — mind you, a work can have more than one author — and also to present the result as a row (tr) with a single cell (td) in a HTML table. Of all posible data from the record, we present, to make it simpler for the time being, only the @xml:id value.

The full XQuery is somewhat more complex, and presents four cells in a row: the @xml:id value, the title, the name of the (first) author, and period when the work was created, if known; provisions are made for records which do not have some of these elements. The result can be seen in our Bitbucket repository (as the croala:oplist function in the croala.xqm RestXQ module), or here:


for $opus in collection("croalabib")//*:listBibl[matches(@ana,'croala.opera')]//(*:bibl|*:biblStruct)[@xml:id]
  order by $opus/*:author[1] collation "?lang=hr"
  return element tr {
    element td { data($opus/@xml:id) },
    element td { 
    if ($opus/*:title) then normalize-space(data($opus/*:title[1])) else "S. t." },
    element td { if ($opus/*:author) then $opus/*:author[1] else "S. a." } ,
    element td { 
    if ($opus/*:date/@period) then data($opus/*:date/@period) else "S. d." }
  }

Basic information on works as a sortable table

Specific cases

Putting it all together

The result, a page displaying a table of IDs, titles, authors and periods for all 4863 works recorded in CroALaBib in our standard project template, can be seen at the following address: croala.ffzg.unizg.hr/basex/croalabib-opera-index.