Difference between revisions of "MilestoneXSLT"
(New page: == Authorship == {| | ''Author'' | Raffaele Viglianti and Elena Pierazzo, King’s College London, [mailto:raffaele.viglianti@kcl.ac.uk raffaele.viglianti@kcl.ac.uk] [mailto:elena.pierazz...) |
(No difference)
|
Revision as of 16:05, 23 June 2008
Contents
Authorship
| Author | Raffaele Viglianti and Elena Pierazzo, King’s College London, raffaele.viglianti@kcl.ac.uk elena.pierazzo@kcl.ac.uk |
| Last revised | 2008-06-23 |
| Previous version | none |
Summary
This is a group of XSLT scripts for managing milestones (page breaks, line breaks, hand shifts, etc.) in XSLT 2.0 (but can work also in 1.0, see below). These scripts are part of a poster presented at DH2008 by Elena Pierazzo and Raffaele Viglianti: XSLT (2.0) handbook for processing multiple hierarchies. Three different approaches are presented, ordered by complexity of the input and of the script as well.
Required Input
Script 1: expanding milestones
<TEI>
<text>
<body>
<p>
Give me then your house & <w>Grounds</w>
<lb/>
I ask for nothing else
</p>
</body>
</text>
</TEI>
Script 2: splitting elements, then expanding milestones
<TEI>
<text>
<body>
<p>
<del rend=”overstrike”>Card room where
<lb/>
nine out of ten had no inclination</del>
</p>
</body>
</text>
</TEI>
Script 3: looping on textual nodes
<TEI>
<text>
<body>
<pb xml:id=”blvolthird-03”/>
<div>
<p><handShift new=”#a2”/>
For James Edward Austen</p>
</div>
<div>
<p><handShift new=”#a2”/>
Jane Austen May 6<hi rend=”sup”>th</hi> 1792</p>
</div>
</body>
</text>
</TEI>
Expected Output
Script 1
the function would produce the following XML fragment as output:
<TEI>
<text>
<body>
<p>
<lb>Give me then your house & <w>Grounds</w></lb>
<lb>I ask for nothing else</lb>
</p>
</body>
</text>
</TEI>
Script 2
<TEI>
<text>
<body>
<p>
<lb>
<del rend=”overstrike”>Card room where</del>
</lb><lb>
<del rend=”overstrike”>nine out of ten had no inclination</del>
</lb>
</p>
</body>
</text>
</TEI>
Script 3
<html>
<body>
<div class=”pb”>blvolthird-03”</div>
<div>
<p><span class=”pencil”>For James Edward Austen</span></p>
</div>
<div>
<p>
<span class=”default”>Jane Austen May 6</span><sip><span class=”default”>th</span></sup> <span class=”default”>1792</span></p>
</div>
</body>
</html>
Known Restrictions or Problems
The code shown below requires XSLT 2. With XSLT 1 it is possible to emulate the “step” approaches by using more than one script and intermediate files
The running time is very similar using a standalone saxon process or embedded in Apache Cocoon
Code
Script 1
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xpath-default-namespace="http://www.tei-c.org/ns/1.0" xmlns:tei="http://www.tei-c.org/ns/1.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8”/>
<xsl:template match="node()|@*">
<!-- Copy the current node -->
<xsl:copy>
<!-- Including any child nodes it has and any attributes -->
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p">
<xsl:variable name="cur-p" select="generate-id(.)"/>
<p><xsl:choose>
<xsl:when test="lb">
<xsl:for-each select="lb">
<lb>
<xsl:sequence select="parent::p/@*"/>
<xsl:apply-templates
select="preceding::*[parent::p[generate-id()=$cur-p]]|preceding::text()[parent::p[generate-id()=$cur-p]]"/>
<xsl:apply-templates
select="preceding::*/@*[parent::p[generate-id()=$cur-p]]"/>
</lb>
<lb>
<xsl:sequence select="parent::p/@*"/>
<xsl:sequence
select="following::*[parent::p[generate-id()=$cur-p]]|following::text()[parent::p[generate-id()=$cur-p]]"/>
<xsl:sequence select="following::*/@*[parent::p[generate-id()=$cur-p]]"/>
</lb>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="."/>
</xsl:otherwise>
</xsl:choose>
</p>
</xsl:template>
</xsl:stylesheet>
Script 2
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xpath-default-namespace="http://www.tei-c.org/ns/1.0" xmlns="http://www.tei-c.org/ns/1.0">
<xsl:output method="xhtml" indent="yes" encoding="UTF-8"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="step1">
<xsl:call-template name="one"/>
</xsl:variable>
<xsl:variable name="step2">
<xsl:apply-templates select="$step1" mode="step2"/>
</xsl:variable>
<xsl:template match="*" mode="step1">
<xsl:copy>
<xsl:sequence select="@*"/>
<xsl:apply-templates mode="step1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="del" mode="step1">
<xsl:variable name="cur-del" select="generate-id(.)"/>
<xsl:choose>
<xsl:when test="lb">
<xsl:for-each select="lb">
<del>
<xsl:choose>
<xsl:when test="parent::del/@type">
<xsl:variable name="type" select="generate-id(parent::del/@type)"/>
<xsl:sequence select="parent::del/@*[generate-id() != $type]"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="parent::del/@*"/>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates
select="preceding::*[parent::del[generate-id()=$cur-del]]|preceding::text()[parent::del[generate-id()=$cur-del]]"/>
<xsl:apply-templates
select="preceding::*/@*[parent::del[generate-id()=$cur-del]]"/>
</del>
<lb>
<xsl:sequence select="@*"/>
</lb>
<del>
<xsl:sequence select="parent::del/@*"/>
<xsl:sequence
select="following::*[parent::del[generate-id()=$cur-del]]|following::text()[parent::del[generate-id()=$cur-del]]"/>
<xsl:sequence select="following::*/@*[parent::del[generate-id()=$cur-del]]"/>
</del>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="one">
<xsl:apply-templates select="TEI" mode="step1"/>
</xsl:template>
<xsl:template match="/" mode="step2">
<html>
<body>
<xsl:apply-templates mode="step2"/>
</body>
</html>
</xsl:template>
<xsl:template match="p" mode="step2">
<xsl:variable name="cur-p" select="generate-id(.)"/>
<p>
<xsl:choose>
<xsl:when test="exists(descendant::lb)">
<xsl:for-each select="descendant::lb">
<xsl:variable name="cur-lb" select="generate-id(.)"/>
<span class="line">
<xsl:for-each
select="preceding::node()[ancestor::p[generate-id()=$cur-p]]">
<xsl:choose>
<xsl:when test="not(self::lb)">
<xsl:if
test="generate-id(following::lb[1])=$cur-lb and generate-id(parent::node()[1])=$cur-p">
<xsl:apply-templates select="." mode="step2"/>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="step2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</span>
<xsl:if test="not(following::lb[parent::p[generate-id()=$cur-p]])">
<span class="line">
<xsl:for-each
select="following::*[ancestor::p[generate-id()=$cur-p]]">
<xsl:apply-templates select="." mode="step2"/>
</xsl:for-each>
</span>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="step2"/>
</xsl:otherwise>
</xsl:choose>
</p>
</xsl:template>
<xsl:template match="del" mode="step2">
<del>
<xsl:apply-templates mode="step2"/>
</del>
</xsl:template>
<!-- OUTPUTTING -->
<xsl:template match="/">
<xsl:sequence select="$step2"/>
</xsl:template>
</xsl:stylesheet>
Script 3
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xpath-default-namespace="http://www.tei-c.org/ns/1.0" xmlns="http://www.tei-c.org/ns/1.0">
<xsl:output method="xhtml" indent="yes" encoding="UTF-8"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="step1">
<xsl:call-template name="one"/>
</xsl:variable>
<xsl:variable name="step2">
<xsl:apply-templates select="$step1" mode="step2"/>
</xsl:variable>
<xsl:template match="*" mode="step1">
<xsl:copy>
<xsl:sequence select="@*"/>
<xsl:apply-templates mode="step1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[not(ancestor::teiHeader)]" mode="step1">
<handShift>
<xsl:sequence select="preceding::handShift[1]/@new"/>
<xsl:value-of select="."/>
</handShift>
</xsl:template>
<xsl:template match="handShift" mode="step1"/>
<xsl:template name="one">
<xsl:apply-templates select="TEI" mode="step1"/>
</xsl:template>
<xsl:template match="/" mode="step2">
<html>
<body>
<xsl:apply-templates mode="step2"/>
</body>
</html>
</xsl:template>
<xsl:template match="p" mode="step2">
<xsl:variable name="cur-p" select="generate-id(.)"/>
<p>
<xsl:choose>
<xsl:when test="exists(descendant::lb)">
<xsl:for-each select="descendant::lb">
<xsl:variable name="cur-lb" select="generate-id(.)"/>
<span class="line">
<xsl:for-each
select="preceding::node()[ancestor::p[generate-id()=$cur-p]]">
<xsl:choose>
<xsl:when test="not(self::lb)">
<xsl:if
test="generate-id(following::lb[1])=$cur-lb and generate-id(parent::node()[1])=$cur-p">
<xsl:apply-templates select="." mode="step2"/>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="step2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</span>
<xsl:if test="not(following::lb[parent::p[generate-id()=$cur-p]])">
<span class="line">
<xsl:for-each
select="following::*[ancestor::p[generate-id()=$cur-p]]">
<xsl:apply-templates select="." mode="step2"/>
</xsl:for-each>
</span>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="step2"/>
</xsl:otherwise>
</xsl:choose>
</p>
</xsl:template>
<xsl:template match="handShift" mode="step2">
<span>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="@new= '#a2'">
<xsl:text>default</xsl:text>
</xsl:when>
<xsl:when test="@new='#a1'">
<xsl:text>pencil</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates mode="step2"/>
</span>
</xsl:template>
<!-- OUTPUTTING -->
<xsl:template match="/">
<xsl:sequence select="$step2"/>
</xsl:template>
</xsl:stylesheet>