Category Archives: Working

Recovering the DB



And so it begins: this is what greeted me when I started eXist after, apparently, mucking about in expathrepo when I wasn’t supposed to. What follows is basically a screenshot diary of the recovery process–I’m not sure I really want to revisit it, but perhaps I’ll come back and add a narrative later…

Yuck. But click into the Java Client, which still works, and you can do the repairs.

ss15 ss16

I think the backup at this point didn’t make much difference. Always back stuff up!
First attempt at repairing didn’t work because the expathrepo directory still existed and therefore couldn’t be rebuilt.
Renaming expathrepo to badbadbad so it can be rebuilt
So many thanks to the twitterverse!
The repair is working!
Repair is done
A new expathrepo directory–now I can delete the corrupted part
Aaaand, we’re back!

No, most definitely not…


Yesterday, I made some progress on displaying file author names in a new column on the front page–figured out how the WORK-TYPES document is called and accessed, how data is retrieved from it, decided it would be better to pull the names directly from the data files, and did it. Sort of. I was running into a problem returning three of the same set of three names for texts with more than one author. But that’s beside the point.

Up I rose this morning, bright-eyed and all, ready to work on my application.

Instead, I saw this:

My morning has been ruined by this.
My morning has been ruined.

Here’s the log in long form. I’m not really sure what happened–things were going swimmingly, yesterday. The DB started, but neither the dashboard nor exide fired, and when I went directly to the app in the browser, I also got some errors. Luckily, I downloaded the app into .XAR, so I have a backup (though I’m not sure how much progress I’d made after downloading the app). I pulled a few other files for backup, and then I downloaded the new eXist release candidate, thinking I could just reinstall and all would be well. But, no. The reinstall worked fine, but the errors are all still there.

To the Internets!


Today a basic display, tomorrow the world?


Thanks in very large part to the patience and availability of a couple of awesome open source developers, I have a basic application that displays the texts in the collection with header info! I haven’t started on formatting, searching, exporting, or incorporating the page images, but soon. Also, I learned where to put the .PNG file for your application icon so it’s visible in the exist-db dashboard (here, as ICON.PNG: C:eXist-dbwebappWEB-INFdataexpathrepoNiC-0.1 — or whatever your app is called). For some reason there’s an empty “title” in the work list, though, which I have to figure out. I also want to add a sort by author and type feature. That should be pretty easy to do, right? Right.

An icon!
Frong page
Sample text

I also was able to add a console module, so I can see what’s getting called where–thanks especially to @wolfgangm. Overall, I’ve been working on simplifying the code so it makes more sense to me and so I can learn how to follow it from point to point. My new XQL page to view the work–like the screen shot above of The Memoirs of Emma Courtney–looks like this:

module namespace tei2=””;
import module namespace console=””;

declare namespace tei=”″;

declare function tei2:tei2html($nodes as node()*) {
for $node in $nodes
typeswitch ($node)
case text() return
case element(tei:TEI) return
case element(tei:teiHeader) return
case element(tei:front) return
case element(tei:body) return
case element(tei:p) return
<p xmlns=””>{$node}</p>
case element(tei:span) return
case element() return
default return

declare function tei2:header($header as element(tei:teiHeader)) {
let $titleStmt := $header//tei:titleStmt
let $pubStmt := $header//tei:publicationStmt
let $sourceDesc := $header//tei:sourceDesc

<div xmlns=”” class=”text-header”>
<h2>By {$titleStmt/tei:author/text()}</h2>

for $resp in $titleStmt/tei:respStmt
<p>{$resp/tei:resp/text()}: {$resp/tei:name/text()} </p>

{ tei2:tei2html($pubStmt/*) }
for $publisher in $sourceDesc/tei:imprint
<li class=”imprint”>{$publisher/tei:publisher/text()}, {$publisher/tei:pubPlace/text()}. {$publisher/tei:extent/text()}. {$publisher/tei:date/text()}. {$publisher/tei:biblScope/text()}. {$publisher/tei:note/text()}</li>

declare function tei2:front($front as element (tei:front)) {
let $frontTitle := $front//tei:head
let $epigraph := $front//tei:epigraph
let $quote := $front//tei:quote
let $bibl := $front//tei:bibl

<div xmlns=”” class=”main-text-frontmatter”>
for $cit in $epigraph

declare function tei2:body($body as element (tei:body)) {
let $para := $body//tei:p

<div xmlns=”” class=”main-text”>
for $para in $body/* (: without the slash asterisk nothing returns–why? : )
<p>{$para//text()}</p> (: adding an extra slash shows the text of the span anas inside each p; with one slash, content of spans are dropped. why? tag is stripped. : )

declare %private function tei2:get-id($node as element()) {
($node/@xml:id, $node/@exist:id)[1]

I know what most of this means, too! (The private function, not so much, nor the logic behind the asterisk and the extra slash in the context above. But still.) So, progress. Yay!


A tiny piece of the puzzle


I think I’ve figured something out that’s been eluding me regarding the way that functions get called–I’m still a bit wobbly on the model/map lingo, but it just occurred to me how the different functions are organized and data passed between XQL and HTML files. The main VIEW-WORK.HTML file calls functions defined in APP.XQL, the primary point of entry. That app uses transformation functions defined in TEI2HTML.XQL–this is part of the separation of powers. There, we have a general TEI2:TEI2HTML function set up as a list of cases–if this element, do that. Then there are more refined functions called TEI2:HEADER and TEI2:BODY declared and implemented here using data passed from the main APP.XQL and the cases in TEI2HTML  I’m still rather foggy about the relationship between the TEI:TEI2HTML cases and the TEI2:HEADER &c results, in part because they use similar naming conventions and one can use information generated in another. I think. And then there’s APP:HEADER, too.

Tomorrow, I want to restructure my sample XML files to include, instead of just <text><body>…</body></text>, a more structured form: <text><front></front><body></body></text>. Then, I want to separate out the front matter (i.e., the subtitle of this document and any epigraph, &c.) from the main body and write functions that display them separately. I also want to figure out why the teiHeader material sometimes displays twice–the relationship between html generated by TEI2:TEI2HTML and by TEI2:HEADER is confusing to me, so I’m hoping that by using smaller functions that do specific things, rather than relying on a series of cases, I can more easily see what’s going on.


Starting fresh


I spent almost all day yesterday trying to figure out why one function worked, and what I thought was pretty much an exact duplicate, tweaked to pull different elements, didn’t–I was pretty frazzled by the end of it, and I think I need to start fresh today (I did put another call out on the exist-db mailing list, and maybe that will yield some insight).

In the meantime, I realize that my lack of vocabulary (what’s a model? what’s a map? what’s a node? lions and tigers and bears!) is a problem. While I’m not going to fix that overnight, I did pull up the W3C recommendations on XQuery 3.0–that will stay open for browsing.

Start from scratch: that’s my plan for today. I’m going to try to write and call a function that just prints out something where I want it to be.


And here’s what I have!

declare function app:test($node as node(), $model as map(*)) {
let $work := $model(“work”)
<p xmlns=””>
{ $work/tei:text/tei:body/tei:p/text() }

The bit in the curly brackets didn’t do diddly, but I did get the word “Testing” to appear beneath the header of my document! I’d say that’s progress for the morning.

Woo hoo!