Xpath12match.xslt

From TEIWiki
Jump to navigation Jump to search

Proof-of-concept that parses out the xpath1() XPointer scheme from the target= of <certainty>. Just to do something with it, it is re-inserted as a new notXSLT:match= attribute. See the recent thread on TEI-L for how the output attribute is different from the XSLT match= attribute, and therefore probably should be named something else.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:notXSLT="http://www.example.org/ns/-1.0"
  xmlns:tei="http://www.tei-c.org/ns/1.0" >
  <!--
    Proof-of-concept that parsing out an xpath() XPointer scheme from a target= is not all
    that hard, at least in the simple case. -->
  <!--
    No atttempt is made to handle harder cases like multiple pointer parts in the fragment
    identifier, or an xpath that itself contains '#', or important parts of the fragment
    identifier are percent-escaped (is that allowed?) -->
  <!-- 
    I make no claim that this is a good way, let alone the best way, to do this. I only
    claim that I thought it would work and that it did on my skimpy test data :-) -->
  <!--
    Written 2009-10-20 by Syd Bauman
    Copyright 2009 Syd Bauman and the Brown University Women Writers Project
    Available under the Creative Commons Attribution-Share Alike 3.0 United States License
    (See http://creativecommons.org/licenses/by-sa/3.0/us/).
  -->
  
  <!-- identity transform: anything and everything (except <certainty>, below) becomes itself -->
  <xsl:template match="/">
    <xsl:apply-templates select="node()"/>
  </xsl:template>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <!-- special processing for <certainty> elements that make use of the xpath1() XPointer -->
  <!-- scheme -->
  <xsl:template match="tei:certainty[contains(@target,'#xpath1')]">
    <!-- remember the base URI specified on target= -->
    <xsl:variable name="baseURI" select="substring-before(@target,'#')"/>
    <!-- remember the fragment identifier (which is an XPointer using the xpath1() scheme) -->
    <xsl:variable name="fragID" select="substring-after(@target,'#')"/>
    <!-- parse the actual XPath out of the xpath1() scheme -->
    <!-- Note the attention to whitespace: we can't just use normalize-space() because the -->
    <!-- XPath scheme itself we are parsing out may have whitespace in it -->
    <xsl:variable name="xpath" select="replace( replace($fragID,'^xpath1\(\s*',''), '\s*\)\s*$','')"/>
    <!-- make a copy of the current <certainty> element ... -->
    <xsl:copy>
      <!-- ... copy its attrs *except* target= -->
      <xsl:apply-templates select="@*[ local-name(.) != 'target' ]"/>
      <!-- ... if no base URI on input target=, then don't bother with output target= -->
      <xsl:if test="normalize-space( $baseURI ) != '' ">
        <!-- ... iff there was a base URI on the input target=, use that as -->
        <!-- the output target= -->
        <xsl:attribute name="target"><xsl:value-of select="$baseURI"/></xsl:attribute>
      </xsl:if>
      <!-- ... spit out the XPath we parsed out of the fragment identifier into an attr -->
      <!-- of its own -->
      <xsl:attribute name="notXSLT:match"><xsl:value-of select="$xpath"/></xsl:attribute>
      <!-- ... copy over any content of <certainty> -->
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>