PartLines2.xslt
Jump to navigation
Jump to search
This is a demo of one way to keep track of partial metrical lines (encoded with part=I, M, and F — this demo knows nothing of part=Y or N, nor next= and prev=, nor <join>) using XSLT 2.0. As the internal documentation says, there may well be a better way to do this, but this does seem to work.
NB that I have also posted an XSLT 1.0 version, which demonstrates that the same task can be done in XSLT 1, but is much more complicated.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns="http://www.w3.org/1999/xhtml">
<xd:doc scope="stylesheet">
<xd:desc>
<xd:p>This is just a proof-of-concept stylesheet that counts the nubmers
of lines in a TEI <tt><lg></tt> element, keeping track of partial lines.</xd:p>
<xd:p><xd:b>written</xd:b>: 2009-12-18 by Syd Bauman, based on some previous
XSLT 2.0 grouping code I’d written and Michael Kay’s post “RE: [xsl] Number of
elements with a given attribute” to XSL-LIST 2009-12-18 10:07-00.</xd:p>
<xd:p><xd:b>availability</xd:b>: Copyleft 2009 Syd Bauman</xd:p>
<xd:p><xd:b>Known Issues</xd:b>:</xd:p>
<xd:p>Process all <tt><lg></tt> elements that have <tt><l></tt> children,
regardless of how deeply nested they might be</xd:p>
<xd:p>Does not process <tt><l></tt> descendants, so if you had couplets encoded,
this stylesheet wouldn't do much useful</xd:p>
<xd:p>This is only intended to demonstrate that this <xd:b>can</xd:b> be done in
XSLT 2.0, not necessarily to demonstrate the best way to do it. Quite the reverse —
my plan is to post this to XSL-LIST and ask “is this the right way to do this”?</xd:p>
</xd:desc>
</xd:doc>
<xsl:output method="xhtml"
encoding="UTF-8"
indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>table of lines</title>
<meta content="partLines2.xslt" name="generated-by"/>
</head>
<body>
<h1>Lines of poetry displayed as a set of tables</h1>
<xsl:apply-templates select="//tei:lg[child::tei:l]"/>
</body>
</html>
</xsl:template>
<xsl:template match="tei:lg">
<xsl:if test="tei:head">
<h2>
<xsl:value-of select="tei:head[1]"/>
</h2>
</xsl:if>
<table border="1">
<thead>
<th>#</th>
<th>content</th>
</thead>
<xsl:for-each-group select="tei:l" group-starting-with="tei:l[not(@part) or @part='I']">
<xsl:variable name="grp_pos" select="position()"/>
<xsl:for-each select="current-group()">
<xsl:variable name="cur_grp_cnt" select="count( current-group() )"/>
<tr>
<td>
<xsl:value-of select="$grp_pos"/>
<xsl:if test="@part">
<xsl:text> (</xsl:text>
<xsl:value-of select="position()"/>
<xsl:text> of </xsl:text>
<xsl:value-of select="$cur_grp_cnt"/>
<xsl:text>)</xsl:text>
</xsl:if>
</td>
<td><xsl:value-of select="."/></td>
</tr>
</xsl:for-each>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>