<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<!--=============================================================
    This stylesheet is a proof of concept for osisRef resolution.
    It takes any xml document and looks for osisRef attributes. 
    They are check for validity, and if they need resolving, they
    are resolved.

    For an osisRef system such as Bible.KJV, it is assumed that 
    there is a file Bible.KJV.xml in the current directory.

    This script handles up to 3-level osisRefs. I.e. for 
    osisRef Ps.115.3, we'll also check for mappings for Ps.115
    and Ps if we don't find a mapping for Ps.115.3.

    Note that you wouldn't _really_ want to do osisRef resolution
    this way, because it is very slow. You have to parse the whole
    refsys definition file to resolve each reference.

    Harry Plantinga, 2003-02-22.
    ==============================================================-->


<!-- print a welcome message -->
<xsl:template match="/">

Welcome to the XSLT osisRef resolver proof-of-concept.  
<xsl:apply-templates select="*"/>
</xsl:template>


<!-- Check all tags. If any contains @osisRef, check/resolve it -->
<xsl:template match="*">
  <xsl:if test="@osisRef">
osisRef: <xsl:value-of select="@osisRef"/>
    <xsl:choose>
      <xsl:when test="contains(@osisRef,'(')"> -> <xsl:call-template 
	name="resolveRef">
        <xsl:with-param name="osisRef"><xsl:value-of 
	  select="@osisRef"/></xsl:with-param>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>: <xsl:call-template name="validateRef">
        <xsl:with-param name="osisRef"><xsl:value-of 
	  select="@osisRef"/></xsl:with-param>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
  <xsl:apply-templates select="*"/>
</xsl:template>


<!--
     validateRef looks up the reference in the reference system 
     definition file to see if it is legal. 
-->
<xsl:template name="validateRef">
  <xsl:variable name="fromsys">
    <xsl:value-of select="substring-before(@osisRef,':')"/>
  </xsl:variable>
  <xsl:variable name="ref">
    <xsl:value-of select="substring-after(@osisRef,':')"/>
  </xsl:variable>
  <xsl:variable name="xdoc"><xsl:value-of 
    select="$fromsys"/>.xml</xsl:variable>

  <xsl:choose>
    <xsl:when test="document($xdoc)/refSys/osisIDs/osisID[@code=$ref]">
      <xsl:text>Valid!</xsl:text>
    </xsl:when>
    <xsl:otherwise>Not valid.</xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!--
     resolveRef: if the reference contains a (, e.g. Bible(Bible.LXX:Ps.15.2),
     we resolve it into the outer system. 
--> 
<xsl:template name="resolveRef">
  <xsl:variable name="tosys"><xsl:value-of 
    select="substring-before(@osisRef,'(')"/></xsl:variable>

  <xsl:variable name="refpre">
    <xsl:choose>
      <xsl:when test="contains(@osisRef,'(')">
        <xsl:value-of
	    select="substring-before(substring-after(@osisRef,'('),')')"/>
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="@osisRef"/></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="fromsys">
    <xsl:value-of select="substring-before($refpre,':')"/>
  </xsl:variable>
  <xsl:variable name="ref">
    <xsl:value-of select="substring-after($refpre,':')"/>
  </xsl:variable>
    
<!-- xdoc is the refsys def that will have the translation -->
  <xsl:variable name="xdoc">
    <xsl:choose>
      <xsl:when test="contains($fromsys,$tosys)"><xsl:value-of 
        select="$fromsys"/>.xml</xsl:when>
      <xsl:otherwise><xsl:value-of select="$tosys"/>.xml</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="ref1"><xsl:value-of 
	select="substring-before($ref,'.')"/></xsl:variable>
  <xsl:variable name="ref2"><xsl:value-of select="$ref1"/>.<xsl:value-of
	select="substring-before(substring-after($ref,
	concat($ref1,'.')),'.')"/></xsl:variable>

  <xsl:message>=========</xsl:message>
  <xsl:message>ref:   <xsl:value-of select="$ref"/></xsl:message>
  <xsl:message>ref2:  <xsl:value-of select="$ref2"/></xsl:message>
  <xsl:message>ref1:  <xsl:value-of select="$ref1"/></xsl:message>

  <xsl:choose>
    <xsl:when test="document($xdoc)/refSys/refMap[@from=$fromsys
	and @to=$tosys]/map[@from=$ref]/@to"> 
      <xsl:message>case:  ref match</xsl:message>
      <xsl:value-of select="$tosys"/>
      <xsl:text>:</xsl:text>
      <xsl:value-of select="document($xdoc)/refSys/refMap[@from=$fromsys 
	and @to=$tosys]/map[@from=$ref]/@to"/> 
    </xsl:when>
    <xsl:when test="document($xdoc)/refSys/refMap[@from=$fromsys
	and @to=$tosys]/map[@from=$ref2]/@to"> 
      <xsl:message>case:  ref2 match</xsl:message>
      <xsl:value-of select="$tosys"/>
      <xsl:text>:</xsl:text>
      <xsl:value-of select="document($xdoc)/refSys/refMap[@from=$fromsys 
	and @to=$tosys]/map[@from=$ref2]/@to"/><xsl:value-of
	select="substring-after($ref,$ref2)"/>
    </xsl:when>
    <xsl:when test="document($xdoc)/refSys/refMap[@from=$fromsys
	and @to=$tosys]/map[@from=$ref1]/@to != ''"> 
      <xsl:message>case:  ref1 match</xsl:message>
      <xsl:value-of select="$tosys"/>
      <xsl:text>:</xsl:text>
      <xsl:value-of select="document($xdoc)/refSys/refMap[@from=$fromsys 
	and @to=$tosys]/map[@from=$ref1]/@to"/><xsl:value-of 
	select="substring-after($ref,$ref1)"/>
    </xsl:when>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

