Skip to content

Instantly share code, notes, and snippets.

@tonyahowe
Last active December 19, 2015 17:49
Show Gist options
  • Save tonyahowe/5994135 to your computer and use it in GitHub Desktop.
Save tonyahowe/5994135 to your computer and use it in GitHub Desktop.
Working XSLT for the file evelina.xml
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.tei-c.org/ns/1.0" version="2.0">
<xsl:template match="TEI">
<html>
<head>
<title>Evelina; or, The History of a Young Lady's Entrance Into the World</title>
<style type="text/css">
body{
font:13px georgia;
line-height:170%;
margin-top: 20px;
margin-left: 20%;
margin-right: 20%;
}
l {
font: 15px; arial; <!-- the xslt doesn't seem to be putting <l>s around the <l>s! -->
}
</style>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="teiHeader"/>
<!-- keeps teiHeader from displaying -->
<xsl:template match="//div[@type='titlepage']">
<center>
<h1>
<i>
<xsl:value-of select="head"/>
</i>
</h1>
<h2> By <xsl:value-of select="byline"/>
</h2>
<h3>
<p>
<xsl:value-of select="dateline"/>
</p>
</h3>
</center>
</xsl:template>
<xsl:template match="l">
<!-- displays all <l>s -->
<l><xsl:apply-templates/>
</l>
</xsl:template>
<xsl:template match="//div[@type='inscription']">
<h2> Inscription, <xsl:value-of select="salute"/>
</h2>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="l">
<!-- displays all <l>s -->
<xsl:apply-templates/>
<br/>
</xsl:template>
<xsl:template match="//div[@type='preface']" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<h2>
<xsl:value-of select="head"/>
</h2>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="//div[@type='dedication']">
<h2> Dedication, to <xsl:value-of select="salute"/>
</h2>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="//div[@type='letter']">
<h3>
<xsl:value-of select="opener"/>
</h3>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="//div[@type='letter']">
<h2>
<xsl:value-of select="head"/>
</h2>
<h3>
<xsl:value-of select="opener"/>
</h3>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="p">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="//div/floatingText" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<blockquote>
<h2>
<xsl:value-of select="head"/>
</h2>
<h3>
<xsl:value-of select="opener"/>
</h3>
</blockquote>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="//div[@type='enclosedLetter']"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<blockquote>
<h2>
<xsl:value-of select="head"/>
</h2>
<h3>
<xsl:value-of select="opener"/>
</h3>
</blockquote>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
@patrickmj
Copy link

I'm guessing that you are trying to grab a bunch of <p>s from the text, and have them also come out as <p>s in the HTML? I think that'd mean a template for the <p>s

<xsl:template match="p">
<p>
<xsl:value-of select="." />
</p>
</xsl:template>

Then instead of the <xsl:value-of select="p" /> do <xsl:apply-templates match="p"/>

Or something like that, maybe?

Similar thing for the <lb>s

If this is close, it'll also be a way to slap different CSS classes as needed.

HTH!

@tonyahowe
Copy link
Author

Seems weird that one has to "apply templates" each time you've got a subroutine (or whatever they're called). Not sure what this will do when I start adding other structural elements--I'd done this once before, but then things got funky when I wanted to nest.

@patrickmj
Copy link

That is a place where things get funky!

Instead of:

  <xsl:template match="p"> <!-- displays all <p>s as <p>s -->
    <xsl:apply-templates/>
    <p/>
  </xsl:template>

maybe

  <xsl:template match="p"> <!-- displays all <p>s as <p>s -->
    <p>
        <xsl:apply-templates/>
    </p>
  </xsl:template>

And double-check that one of the templates not commented out that uses <p>s is being run

@tonyahowe
Copy link
Author

The newest one is up now... Rrr. It's driving me crazy! Couple things:

  • the s don't actually, in the source, have s around them, apparently. Why?
  • each block of text repeats its or . Why?
  • in the xml, I'm getting notices of ambiguous rule matches, as follows:

System ID: C:\Users\Tonya\Dropbox\DHOXSS 2013\epistolary.xsl
Scenario: xml-stylesheet processing instruction
XML file: C:\Users\Tonya\Dropbox\DHOXSS 2013\evelina.xml
Engine name: Saxon-PE 9.5.0.2
Severity: warning
Description: XTRE0540: Ambiguous rule match for /TEI/text[1]/body[1]/div[2]/lg[1]/l[1] Matches both "element(Q{http://www.tei-c.org/ns/1.0}l)" on line 62 of file:/C:/Users/Tonya/Dropbox/DHOXSS%202013/epistolary.xsl and "element(Q{http://www.tei-c.org/ns/1.0}l)" on line 49 of file:/C:/Users/Tonya/Dropbox/DHOXSS%202013/epistolary.xsl
URL: http://www.w3.org/TR/xslt20/#err-XTRE0540

@patrickmj
Copy link

hmm....missing some info, probably because of missing backticks ( ` ) in the comment

Without backticks:

s

With backticks around the element:

<p>s

The markdown code:


Without backticks:

<p>s

With backticks around the element:

`<p>`s

@tonyahowe
Copy link
Author

Hah! What I meant to say was...

  • the <l>s don't actually, in the source, have <l>s around them, apparently. Why?
  • each block of text repeats its <opener> <head> or <salute>. Why?

@greystate
Copy link

Couple of points:

  • Using apply-templates is actually how XSLT works :-)
  • You don't need to write match="//div" - match="div" works just the same (and looks better :-)
  • The <l>s don't get copied because your template instructs the processor to "continue" (apply-templates)
  • The repeated opener, head etc. are due to them being output explicitly by the template first, then by the apply-templates at the end of the template - you could modify the template(s) (mind you, I don't know how your XML looks) to something like this:
<xsl:template match="div/floatingText | div[@type = 'enclosedLetter']">
    <blockquote>
        <h2>
            <xsl:value-of select="head"/>
        </h2>
        <h3>
            <xsl:value-of select="opener"/>
        </h3>
    </blockquote>

    <!-- Process remaining children -->
    <xsl:apply-templates select="*[not(self::head or self::opener)]" />

</xsl:template>

Note that you can match more than one type if the output is the same.

  • It's worth noting as well, that everytime you just want the element copied to the output (e.g. <p> or <l>) you can have a generic copy template do that, so you don't have to explicitly create it - just make sure to remove the existing p and l templates if you use this, e.g.:
<!-- Identity transform -->
<xsl:template match="*">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:apply-templates select="* | text()" />
    </xsl:copy>
</xsl:template>

Hope that helps a bit...
/Chriztian

@tonyahowe
Copy link
Author

Whoa, thanks Chriztian! Just learning, so this is a big, big help. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment