Change2change.xslt

From TEIWiki
Jump to navigation Jump to search

The P5 <change> element is significantly different than the P4 <change> element. This stylesheet reads in a TEI P4 XML file and writes out the same file but with P5-format <change> elements.


<?xml version="1.0" encoding="utf-8"?>

<!-- Tiny XSLT 1.0 stylesheet that reads in a TEI file with <change> elements -->
<!-- that conform to P4, and writes out the same with <change> elements that -->
<!-- are likely to conform to P5 (pre-release 0.3.1). -->
<!-- Copyleft 2006 Syd Bauman and the Text Encoding Initiative Consortium -->

<!-- The output of this stylesheet is not P5-compliant XML; in fact, even the -->
<!-- one element we are changing, namely <change>, may not be valid P5. This is -->
<!-- because although we move all the bits of information to the right place, it -->
<!-- may still be in the wrong format. E.g., a <date value="2006-01-31">31 Jan -->
<!-- 06</date> will be transformed to the valid when="2006-01-31", but a <date>31 -->
<!-- Jan 06</date> will be tranformed to the invalid when="31 Jan 06". -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:tei="http://www.tei-c.org/ns/1.0"
                version="1.0">

  <xsl:import href="Copy-All.xsl"/>

  <xsl:output method="xml"
    encoding="UTF-8"
    cdata-section-elements="eg"/> 

  <!-- special template for <change> elements that have to change -->
  <xsl:template match="revisionDesc/change">
    <xsl:element name="change">
      <xsl:attribute name="when">
        <!-- For the value of the new when= attribute ... -->
        <!-- look at my child <date> element, -->
        <xsl:choose>
          <!-- if it has a value= attribute, use its value -->
          <xsl:when test="./date/@value">
            <xsl:value-of select="./date/@value"/>
          </xsl:when>
          <!-- if not, use its content -->
          <xsl:otherwise>
            <xsl:value-of select="./date/text()"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:attribute name="who">
        <!-- For the value of the new who= attribute ... -->
        <!-- look at my child <respStmt>'s first <name> child ... -->
        <!-- (warn if there's more than 1 <name> child of <respStmt>) -->
        <xsl:if test="count(./respStmt/name)>1">
          <xsl:message> warning: more than one <name> child of <respStmt>, using the first </xsl:message>
        </xsl:if>
        <xsl:variable name="respName">
          <xsl:choose>
            <!-- ... if it has a key=, use its value -->
            <xsl:when test="./respStmt/name/@key">
              <xsl:value-of select="./respStmt/name/@key"/>
            </xsl:when>
            <!-- ... if no key=, if it has a reg=, use its value -->
            <xsl:when test="./respStmt/name/@reg">
              <xsl:value-of select="./respStmt/name/@reg"/>
            </xsl:when>
            <!-- ... neither key= nor reg=, use content -->
            <xsl:otherwise>
              <xsl:value-of select="./respStmt/name/text()"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <!-- ... now that we have a name, strip out icky characters -->
        <xsl:variable name="respVal" select='translate(normalize-space($respName),"-,'&#$%^!~`={}[]<>?/:; +=\|@","-")'/>
        <!-- [Note that hyphens are left in place, as they are valid NAME characters.] -->
        <!-- This is not the right way to do this. What we really want is not to strip -->
        <!-- out the few non-NAME characters I can think of and type easily, but rather -->
        <!-- we'd prefer to keep only the NAME characters and ditch everything else. -->
        <!-- I don't know if that can be done in XSLT 1.0, and if it can, I don't know -->
        <!-- how to do it. Note also that we do not check that the first char is -->
        <!-- a NAMESTART character. -->
        <!-- ... and stick a "#" in front -->
        <xsl:text>#</xsl:text>
        <xsl:value-of select="$respVal"/>
      </xsl:attribute>
      <!-- content of new <change> is the content of old <change>'s child <item> -->
      <xsl:apply-templates select="./item/*|./item/text()|./item/processing-instruction()|./item/comment()"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

Syd 06:51, 26 May 2006 (BST)