XPath

Below is an extended explanation of XPath which I recommend reading no matter what your level of coding.1 So often, when code is not working as it should, the issue is an XPath issue, as mentioned in the portion of this textbook on troubleshooting.

The XPath language operates in very much the same way as paths between items in folders but it can reach down into and grab portions of XML documents inside them. Learning this language is necessary for reading, amending, and writing programs in XSLT.

XML documents are structured hierarchically, and consequently people use the terminology of family trees when discussing its elements / tags or rearranging them programmatically. A tag and everything inside it is called a "node."

Here, to the right, you can see a generic XML file. a generic xml file

In oXygen, you can click on the Window in the topmost menu to open an outline view of your XML document, click on the window menu, then Show View

revealing the hierarchical "tree" structure of your XML document. Outline view in oXygen

The generic XML file, a book with parts, can be illustrated abstractly as a family tree.

Below, you see an abstract rendition of an XML document heirarchy, including the genealogical terms used to describe the various nested levels.

an abstract XML document tree

Now, I have redrawn it as a family tree to better illustrate the terms used. The terms are, however, relative: a child can be a parent and vice versa.

family tree of abstract XML document

Before writing an XPath and showing you how to use XPath in order to navigate around this document structure, pictured above, I need to explain WHY we need to understand XPath.

You will be using xslt programs to transform your TEI / XML encoded documents into HTML / web pages. XSLT needs XPath, and so many mistakes in writing xslt programs have to do with bad XPaths, as we will see.

Programming mistakes in xslt are inevitable: you need to understand how paths work conceptually, but when you are amending or writing your own xslts, that's when you actually work out the XPaths that you need to write at any given moment. You do not have to memorize anything presented here!

XML documents are made up of nodes. XSLT transforms operate using "templates": these templates match any given node and then describe what to do with it. As you can see to the right, the template in the xslt that matches "paragraph" in the XML document transforms it into a "p" in the HTML document that it creates. See also a video about how xslt works.

xslt works by selecting nodes

the XML code the HTML code the web user's view

Back to learning the concepts of XPath.

Typically, the first item in an XPath is a child of the context node. The beginning of the path is simply the child name. I need to use forward slashes after the name if I am navigating to a child of that child. In the context of the Root of this document, at the very top of the hierarchy, the XPath to navigate to "nodeB" is node1/nodeB
(child::node1/child::nodeB).
path from Root to node B

Remembering the introduction to File Structure in the HTML section of this web textbook, the XPath above is just like the "relative path" for moving from one folder into another. a path inside the Mary Leapor folder

Let's write a more complicated XPath, starting at a context within the yellow square and moving through the hierarchy to the red square: diagram of a hierarchy

To the right, you can see the path written in the abstract and metaphorical terms of a genealogy, a family tree.

If I am the yellow square, I have two parents: the first one is my parent, the second, my parent's parent. (To take the metaphor too far, I'm going to visit my grandmother's niece, my Great Aunt's daughter.)

path in the hierarchy

Now, we will look at in detail at diagrams exploring the TEI document hierarchy in order to write a real XPath. The code for the documents discussed in this final section of XPath, as well as the image to the right, can be downloaded here. the TEI hierarchy

Let's go over the parts of a TEI document slowly. A TEI document has two children, the teiHeader and the text. top hierarchy of the TEI document tree

The text element in TEI only HAS to have one child, a body child, but it can have a front and back as well. second level of the TEI document tree

Below you can see a poem encoded in TEI, containing the elements lg ("line group" or a stanza) and l (lines of poetry). This poem has four stanzas, each containing a varying number of lines.

a poem in TEI

Below you see the entire TEI document with the teiHeader element blurred out.2

whole document without the teiHeader

Called "pseudoPoem.xml" in the documents provided, this TEI document in a digital edition contains front matter and three div tags in its body: one contains a poem, the second a paragraph about the author, and the third is a two-paragraph coda. All the div tags contain head elements:

document structure, elements highlighted

While transforming the TEI-encoded document into a text file, the xslt is also going to pull the second paragraph from the coda into a note to the third line of the first stanza of the poem.

Inside the note element, there is a ref tag enclosing text that will precede the paragraph we are quoting -- that is, the Coda paragraph that we will call into the note.3 In other words, the ref node is our starting context.

We start in our ref tag (circled in yellow) on the self axis and move up five parent axes to the body node, then down into the body's third child, a div tag on the far left (the number 3 is given in brackets in XPath, instructing it to select the third child), and down again to grab the second paragraph, p[2], in that div.

following a path

Here is that XPath again:
the path as typed

But we can also take a shortcut: instead of going all the way up into the body element, we can skip that step by using the sibling axis. Notice that we selected the second div sibling, the second one following itself.

path shortcut

Why has the div node number changed from [3] to [2] in the image above? The parent node, "body," has three children, three divs; each of the children div nodes have two siblings.

Here is that XPath again:

path shortcut

Each part of these paths separated by / is a step up or a step down the genealogical hierarchy.

While it is important to understand these paths conceptually, you will rarely have to write something so elaborate. For example, you never actually have to specify the originating context, the the self axis -- that's understood. And it is only if you are going to go from your context anywhere besides down the hierarchy to children that you have to include any axis information at all.

These two paths are the same:

paths

And these two paths are the same:

paths

In both shorter paths, neither self::ref nor child:: are stated; they are implicit, default.

Given that the child axis never needs to be stated, if my context is that third div, I can get to my second paragraph without introducing it as a child::. The child axis is default.

shortest path

Below you can see a shortcut that takes you up the document to the root node and then down into the text, and down further into the body's third div, second paragraph. The first, single forward slash, /, means, "go all the way up to the root element," here TEI:

short path illustration

Yet another shortcut involves using the ancestor-or-self axis:

ancestor or self path

And finally, the shortest shortcut takes me directly to the third div. Two forward slashes together, //, mean, "go to this particular element anywhere in this document":

Counting divs works because we only have three of them in this TEI document — the poem div's siblings pictured above. However, in the TEI document, the second paragraph that we want is in a div tag that has the type attribute with a value coda, and, using the sign for attributes --

using attributes to select one element with many siblings

Almost every problem one has in getting one's XSLT's to work has to do with XPath.

Back to Top



Notes

1. An excellent explanation of XPath can be found in Clifford B. Anderson and Joseph C. Wicentowski, XQuery for Humanists (College Station, TX: TAMU Press, 2020), pp. 55-78. Another excellent explanation can be found in David Birnbaum, XSLT for Humanists, forthcoming. Here, I will explain XPath only in relation to the interactions among css, HTML, TEI/XML, and xslt. Back

2. The teiHeader, as a vehicle for metadata about both the original text and the digital surrogate that you are creating (the digital edition), can be very complex, and we deal with that in the TEI section of the web textbook called "teiHeaders." It's best to ignore that complexity here. Back

3. This example is obviously contrived to provide difficulty, but you could imagine wanting to pull text from somewhere else so that the somewhere else can be changed without having to revise the note. Back