dorothealint / Rick-and-Morty

Digital Humanities project marking up and analyzing data from Rick and Morty
The Unlicense
1 stars 1 forks source link

XSLT TEI to XHTML Transformations #19

Open helvitiis opened 6 years ago

helvitiis commented 6 years ago

I'm having some trouble transforming the TEI scripts to one HTML file containing all of them. This is what I have so far:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="http://www.tei-c.org/ns/1.0"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    xmlns="http://www.w3.org/1999/xhtml"
    version="3.0">

    <xsl:output method="xhtml" encoding="utf-8" doctype-system="about:legacy-compat"
        omit-xml-declaration="yes"/>
    <xsl:variable name="coll" select="collection('episodes')"/> 
    <xsl:mode on-no-match="shallow-copy"/>
    <xsl:template match="/">
        <html>
            <head>
                <title>Transcripts</title>
            </head>
            <body>
                <xsl:apply-templates select="$coll//body" />
            </body>
        </html>
    </xsl:template>
    <xsl:template match="$coll//body">
        <br/>
        <h2>
            <xsl:apply-templates select="//head/title"/>
        </h2>
        <p>
            <xsl:apply-templates select="//body"/>
        </p>
    </xsl:template>
    <xsl:template match="speaker">
        <strong> <xsl:apply-templates/> </strong>
    </xsl:template>
    <xsl:template match="sp">
        <div class="sp"> <xsl:apply-templates/> </div>
    </xsl:template>
    <xsl:template match="stage">
        <div class="stage"> <xsl:apply-templates/> </div>
    </xsl:template>
</xsl:stylesheet>

I'd like to put all of the transcripts on the server so I can add JS and CSS next. I will need to change a lot of the elements to HTML-valid ones as well but I am still working on those. I'm continuing to get one error in particular: XPTY0019: Required item type of first operand of '/' is node(); supplied value has item type xs:base64Binary.

Here are all of the files: https://github.com/dorothealint/Rick-and-Morty/tree/dad53a0357440ec7320b4c45f462349c8549b1fc/scriptFiles/transformationsFolder

Any tips would be greatly appreciated!

@dorothealint @ebeshero

ebeshero commented 6 years ago

@quantum-satire Change this template match:

 <xsl:template match="$coll//body">

to

 <xsl:template match="body">

Remember, XSLT is just looking for an XPath pattern in the template @match attribute. You've already selected where to find all those body elements in your first template rule. The @select in <xsl:apply-templates> has to be the literal XPath that prunes the part of the collection tree that you want to process with the later template rules.

Does that change work?

helvitiis commented 6 years ago

@ebeshero Thanks for the quick response!

Here is the error I am getting: screen shot 2018-04-15 at 8 43 37 pm

ebeshero commented 6 years ago

@quantum-satire You changed the wrong line!

ebeshero commented 6 years ago

@quantum-satire Before you very properly had this as your first template rule. I think you misunderstood what I was saying in my commentary about it.

<xsl:template match="/">
        <html>
            <head>
                <title>Transcripts</title>
            </head>
            <body>
                <xsl:apply-templates select="$coll//body" />
            </body>
        </html>
    </xsl:template>

You want xsl:apply-templates to "prune the tree" of your collection and indicate WHAT'S to be processed. You do not want to start a new template rule inside another template rule--that's not how we write XSLT, and the computer is now very properly telling you off about that.

ebeshero commented 6 years ago

@quantum-satire Look at your second template rule, and change its @match attribute as indicated above.

helvitiis commented 6 years ago

@ebeshero Whoops--I changed the line I was having an error crop up on there. screen shot 2018-04-15 at 8 50 20 pm

ebeshero commented 6 years ago

Okay there are a number of problems here now that I take a closer look.

1) Using <xsl:mode on-no-match="shallow-copy"/> doesn't make sense here, does it? That is for an XML to XML identity transformation! None of your elements can remain the same in TEI to HTML transformation because you're shifting namespaces at the very least. 2) I think this error you're seeing has to do with not being able to locate the collection. Where is your XSLT file sitting in relation to it in your repo? Is it up a parent directory and down into another directory? If your collection is in a directory named episodes, and that directory is positioned in the same level as the XSLT file (as in the XSLT file is just above it, or like a sibling of it so that they are both inside the same directory), then this should work. You could try putting a /* here like so:

<xsl:variable name="coll" select="collection('episodes')/*"/> 

3) You also need to work on this rule:

 <xsl:template match="body">
        <br/>
        <h2>
            <xsl:apply-templates select="//head/title"/>
        </h2>
        <p>
            <xsl:apply-templates select="//body"/>
        </p>
    </xsl:template>

One thing you really need to change those leading forward slashes in your @select attributes on <xsl:apply-templates> in this rule. Remember what those mean? You want to replace them with descendant::head//title...and wait a minute, why would you have a descendant body to process inside the body element that you've matched on?

ebeshero commented 6 years ago

@quantum-satire Okay--the syntax of your collection() function is probably okay. I just checked it against my model here: http://dh.newtfire.org/XSLTExercise5.html

And I see you've placed the episodes directory at the same level as your XSLT so that should be okay, too.

Here's one very simple thing to check: You do need to select something in oXygen as your input XML document, even though it is kind of a "dummy" file. Do you have an XML file selected in the input window?

helvitiis commented 6 years ago

@ebeshero I do have a file from the collection that is working as an input XML document, and just in case, I closed it and re-opened it, then re-ran the transformation again. Still getting the same error...

ebeshero commented 6 years ago

@quantum-satire Hmmm. Okay--let me pull this in and take a closer look--I'll try running it from here. It sounds like the collection isn't being accessed at all, and I have a hunch I've seen this problem before...

helvitiis commented 6 years ago

@ebeshero Could this be a DS_store issue?

ebeshero commented 6 years ago

@quantum-satire YES--that's it! Can you run that script I posted on the DHClass-Hub? Hang on, I'll post a link.

ebeshero commented 6 years ago

https://github.com/ebeshero/DHClass-Hub/wiki/Banishing-DS_Store,-Thumbs.db,-and-other-pesky-files-we-don't-need

helvitiis commented 6 years ago

@ebeshero I followed the instructions and deleted the DS_store files from my computer as well as navigated the "long way" through the GUI, then ran the transformation again. Another error has popped up to make life more difficult! screen shot 2018-04-15 at 9 36 45 pm

ebeshero commented 6 years ago

@quantum-satire It is perhaps fitting, quantum-satire, that you have written code that is quantum-looping... ;-) Look at my advice on that second template rule above. Do you really want to start a @select attribute with leading forward slashes?

ebeshero commented 6 years ago

@quantum-satire Quoting myself a few messages back: One thing you really need to change those leading forward slashes in your @select attributes on <xsl:apply-templates> in this rule. Remember what those mean? You want to replace them with descendant::head//title...and wait a minute, why would you have a descendant body to process inside the body element that you've matched on?

helvitiis commented 6 years ago

@ebeshero Is this heading in the right direction?

<xsl:template match="body">
        <br/>
        <h2>
            <xsl:apply-templates select="descendant::title"/>
        </h2>
        <p>
            <xsl:apply-templates select="descendant::body"/>
        </p>
    </xsl:template>
ebeshero commented 6 years ago

@quantum-satire Yes, but why would you apply-templates to a descendant::body element when you are template matching on body already? Do you mean to select something else there? Or do you just want a general <xsl:apply-templates>, which would apply template rules to all the children and descendants of body? My guess is you want something within body here, and probably you want to apply-templates to descendant::p instead.

ebeshero commented 6 years ago

@quantum-satire Also, is the <title> element a descendant of <body> in your source XML? If it is, apologies, but often that's an element up in the TEI Header and not down in the body portion of a TEI document.

ebeshero commented 6 years ago

@quantum-satire If you're wanting to create a surrounding <p> element around paragraphs, though, that's going to be a problem--usually there are multiple paragraphs, so I'm probably wrong in my guesses unless I look at your source XML. Anyway, what do you want to be output in a single <p> element after the title?

ebeshero commented 6 years ago

@quantum-satire Studying your source XML from here, I can see that <title> is never a descendant:: of <body>. You need to start your journey from body to title using a different XPath axis. Remember ancestor::? Climb up from the context of your template match to the thing you want to process. You really need to study your source code.

helvitiis commented 6 years ago

@ebeshero You're right, <xsl:apply-templates select="//teiHeader/descendant::titleStmt/title"/> did the trick and I am now getting output for it!

Here is a sample of our XML:

<stage>Jerry enters the living room, where a tree stands with presents underneath it. Beth and Morty are occupied on tablets while Summer uses her smartphone.</stage>
<sp><speaker>Jerry</speaker><p> Um, Merry Christmas? <stage>puts his hands on his hips</stage> Helloooo? My parents are coming over for the first time in years! Can we stow the gadgets and look alive?</p></sp>
<sp><speaker>Beth</speaker><p> Alive? For your parents?</p></sp>

I thought that wrapping divs around each line would be a solution to keeping the <p> elements the way they're formatted now, so the output would become something like this:

<div class="stage">Jerry enters the living room, where a tree stands with presents underneath it. Beth and Morty are occupied on tablets while Summer uses her smartphone.</div>
<div class="sp"><strong>Jerry</strong><p> Um, Merry Christmas? <stage>puts his hands on his hips</stage> Helloooo? My parents are coming over for the first time in years! Can we stow the gadgets and look alive?</p></div>
<div class="sp"><strong>Beth</strong><p> Alive? For your parents?</p></div>
helvitiis commented 6 years ago

Though this may be messy now that I look at it...

ebeshero commented 6 years ago

@quantum-satire Glad you got it working! :-) Make sure the output is valid HTML (save and open in oXygen...) I think this could work for styling. I'd recommend outputting speakers in <span class='speaker'> in case you decide you want to style them in some way other than strong. Technically <strong> has a semantic meaning of emphasis even in HTML, when you just want some special styling for your speakers.

helvitiis commented 6 years ago

@ebeshero I like span better than div, I think I will probably go with that. Too many div boxes on a page can get confusing quickly as far as styling--and I want to make sure the code is as valid as possible as well when it comes to span vs strong.

helvitiis commented 6 years ago

@ebeshero Unfortunately, I'm still working on the XSLT transformation for the transcripts page. @dorothealint and I are meeting on campus today to try and debug what's going on, but I'm just getting odd errors again. I made sure to clear out the .DS_store files before running any of the transformations, but the error continually says "collection(): failed to parse XML file" Here is the latest commit: cbe77c4d8b2172c30168f72d5d0f614741e099a2 I think my XSLT is correct...

ebeshero commented 6 years ago

@quantum-satire No worries-- I'm on campus this afternoon if you need some help debugging!

helvitiis commented 6 years ago

@ebeshero That would be awesome! How late will you be on campus? We will definitely stop by :)

ebeshero commented 6 years ago

@quantum-satire Probably until 3 or 4 pm? I'm meeting with a graduating Digital Studies certificate student at 1pm to make sure he can update his old newt fire website--It may not take too long (I sent him instructions on the SSH keys ahead of time...)

helvitiis commented 6 years ago

@ebeshero Ah, the dreaded setup of SSH keys! Dorothea and I will probably stop by around two-ish, hopefully that works for your schedule!