NewtFire logo: a mosaic rendering of a firebelly newt
newtFire {dh}
Creative Commons License Last modified: Wednesday, 28-Oct-2020 18:28:31 UTC. Maintained by: Elisa E. Beshero-Bondar (eeb4 at psu.edu). Powered by firebellies.

Getting started

Our very first XSLT assignment is an Identity Transformation, a kind of transformation we have to do frequently in our projects when we need to make specific changes to our encoding. For this exercise, we will write XSLT to make some repairs to an XML document from the Fall 2020 Elder Scrolls Morrowind project.

Begin with a directory of files posted on the digitProjectDesign-Hub. Using your Terminal (on Mac) or your Git Bash Shell (on Windows), update your local clone of the digitProjectDesign-Hub with git pull. We will work with files in the Class Examples > XSLT > identityTransform directory. Open your <oXygen/> XML Editor, and open the XML file named STARTguide2Balmore.xml in that directory. (There is a Relax NG chema saved along with the files, and you will see that it is firing many validation errors on this document. That is because we made changes to the schema after this document was encoded, and we need to bring the XML document up to date with the new schema.

Our task is to deal with the validation errors in the document using an XSLT identity transformation. We do not want to change much of contents of this file, but we do want alter its tagging a little so the document will be valid according to its schema. That is a good occasion to write an Identity Transformation XSLT, converting our XML to XML that is meant to be (for the most part!) identical to the original.

Open a new XSLT file (version 3.0) and toggle the XSLT Debugger view so you can work on your XSLT transformation code in between the source XML and an output panel.(Or you may begin with the starter XSLT document provided in the same GitHub directory.)

The problems we need to fix

Looking through the file, we can see the following tagging issues that are raising errors:

Here is what we want to do to repair the file.

You may already be calculating how to do these tasks with regular expression using Find and Replace, and while we know you could do that, our purpose is to make the changes using an XSLT transformation, and we hope you will learn some things about how XSLT works through this exercise.

Writing the Identity Transformation!

  1. We will give you your first transformation code, to set the mode of this XSLT to be an identity transformation. We’re going to use a new form for this in version XSLT 3.0, so that is why we have set version="3.0" in our stylesheet template above. (You can see an old form here in the first template rule of our Identity transformation of Shakespeare’s sonnets, which you can download, save and open from here. That old first rule matches on all nodes, elements and attributes throughout the document and simply copies them. It’s perfectly fine to use that older template rule in place of the one we show you below, but we like the simplicity of this new form even better!).
    <xsl:mode on-no-match="shallow-copy"/>

    This XSLT statement is the opposite of the xsl:template match we have been showing you in our XSLT tutorial. You basically say, if I do not write a template rule to match an element, attribute, or comment node, really of any part of the document that I do not mention in a template match rule, XSLT should simply make a copy of that element and output it. Try running this and look at your output: it will look exactly identical to the current XML document. Obviously we do not need to do this unless we want to make changes with template match rules! There is another way to copy, called "deep copy" in XSLT, but we do not want use it here. When you use "deep copy" in XSLT, you reproduce the full directory tree underneath a given element, so the understanding is that we would match on the root element only, and reproduce all the descendents of that one node just as they are. We like the "on-no-match-shallow-copy" approach because we need to step through the document tree just one step at a time. We only want to copy a node if we do not want to write a new template rule that will change it.

  2. Next, we will simply write our template rules to match on the particular elements we wish to change. You may wish to start with the simplest of the changes, to match the <NPC> elements and simply remove all the @who attributes from them in the output XML. Review our Introduction to XSLT to see how to write a template match on any particular element, and how to output an altered element in its place, and continuing to process its descendants using <xsl:apply-templates/>.
  3. When we write XSLT, we often work with Attribute Value Templates (or AVT), a handy special format in XSLT that helps us to pull information from our source document and position it exactly where we want to inside an attribute value. You need to look at some examples of AVTs in order to write one yourself, so for the next tasks, go and look at the examples in Obdurodon’s Attribute Value Templates (AVT) tutorial. After reading the AVT tutorial, write two more template rules.
    • Write a template rule to match the <who> elements that have @xmlid attributes in the source document. In your template rule, reconstruct the <who> element so that you rename the attribute, and write an AVT to return the value you want. Ideally, you want to do a little string surgery on the original value: You want to output only the first part of it, the portion before the first space. Hint: There is a convenient XPath function for this: tokenize(). You could use the tokenize() function to break the value into tokens using its spaces, and indicate with a position predicate ([1])that you just want to output the first token.
    • Write another template rule to match the <location> elements that have @xmlid attributes. Set a new attribute, @ref, and again, set an ATV to pull its value, and again try a little string surgery: This time, try the translate() or replace() function to convert the spaces in the original values into hyphens.
    • Finally, this time, notice there is another attribute present on the <location> elements, @visitable, that we definitely need to preserve in the output! Be careful not to lose it. As you remodel the location element, you can simply set the original attribute in place and use an ATV to set its value.
    • You will be looking at your results in the Output window as you write and test your template rules each time you press the blue Run-to-End button. Eye-balling those results is not really enough because the Output window does not check for well-formedness or validation against a schema. Be sure to save those results, either by setting an output location in the appropriate place in the selection boxes, or by right-clicking on the output window and selecting Save as. Always, always open the saved output file in <oXygen/> and check to make sure that it checks out as valid and well-formed. Your new output should address all of the schema validation errors and return a green square.

Submitting your work

When you are finished, save your XSLT file and your XML output of the Elder Scrolls Morrowind file, following our usual homework file naming conventions, and upload these to the appropriate place in Canvas.