<?xml version="1.0" encoding="UTF-8"?>
<!--
This stylesheet provides named and unnamed templates for processing data that is compatible to the BioTypes schema (http://schemas.bioservices.net/2005/biotypes). To use the templates in a stylesheet it must be imported:

<xsl:import href="biotypes.xsl"/>

For further information please visit http://schemas.bioservices.net.

Content is available under Creative Commons Attribution-ShareAlike License. See http://creativecommons.org/licenses/by-sa/2.0/.

Change log:

05/24/2005 by [http://szugat.gmxhome.de Martin Szugat]: Bugs fixed: mapSource searches schemas only within xs:schema/xs:*/@schemaLocation; breakText now works within Internet Explorer.
05/21/2005 by [http://szugat.gmxhome.de Martin Szugat]: Initial version.
-->
<xsl:stylesheet 
  id="BioTypes"
  version="1.0"
  exclude-result-prefixes="xs xsl bt xsi"
  xmlns:bt="http://schemas.bioservices.net/2005/biotypes"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
  
  <xsl:param name="textColor" select="'red'"/>
  <xsl:param name="lineLength" select="60"/>

<!--
Uncomment the following lines to use this stylesheet as a standalone stylesheet which can used to test some of the templates.
-->
<!--
  <xsl:output method="html" />

  <xsl:template match="/">
    <html>
      <head>
        <title>Sources</title>
      </head>
      <body>
        <table border="1">
          <tr>
            <th>
              <xsl:text>source</xsl:text>
            </th>
          </tr>
          <xsl:for-each select="//*[@source]">      
            <tr>
              <td>
                <xsl:variable name="url">
                  <xsl:call-template name="mapSource">
                    <xsl:with-param name="to" select="'url'"/>
                  </xsl:call-template>
                </xsl:variable>
                <xsl:variable name="caption">
                  <xsl:call-template name="mapSource">
                    <xsl:with-param name="to" select="'caption'"/>
                  </xsl:call-template>
                </xsl:variable>
                <a>
                  <xsl:if test="$url != ''">
                    <xsl:attribute name="href">
                      <xsl:value-of select="$url"/>
                    </xsl:attribute>
                  </xsl:if>
                  <xsl:choose>
                    <xsl:when test="$caption != ''">
                      <xsl:value-of select="$caption"/>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="@source"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </a>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
-->
  <xsl:template name="breakText">
    <xsl:param name="text" select="''"/>
    <xsl:param name="from" select="string-length($text) + 1"/>
    <xsl:param name="to" select="string-length($text) + 1"/>
    <xsl:if test="$text != ''">
      <xsl:call-template name="colorText">
        <xsl:with-param name="text" select="substring($text, 1, $lineLength)"/>
        <xsl:with-param name="from" select="$from"/>
        <xsl:with-param name="to" select="$to"/>
      </xsl:call-template>
      <xsl:if test="$lineLength &lt; string-length($text)">
        <br/>
        <xsl:call-template name="breakText">
          <xsl:with-param name="text" select="substring($text, $lineLength + 1)"/>
          <xsl:with-param name="from">
            <xsl:choose>
              <xsl:when test="$from - 1 &lt; $lineLength ">
                <xsl:value-of select="1"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="$from - $lineLength"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:with-param>
          <xsl:with-param name="to" select="$to - $lineLength"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:if>
  </xsl:template>
  
  <xsl:template name="colorText">
    <xsl:param name="text" select="''"/>
    <xsl:param name="from" select="1"/>
    <xsl:param name="to" select="string-length($text)"/>
    <xsl:if test="$from &gt; 1">
      <xsl:value-of select="substring($text, 1, $from - 1)"/>
    </xsl:if>
    <xsl:if test="$from &lt;= string-length($text)">
      <font>
        <xsl:attribute name="color">
          <xsl:value-of select="$textColor"/>
        </xsl:attribute>
        <xsl:value-of select="substring($text, $from, $to - $from + 1)"/>
      </font>
      <xsl:if test="$to + 1 &lt;= string-length($text)">
        <xsl:value-of select="substring($text, $to + 1)"/>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <xsl:template name="mapSource">
    <xsl:param name="document" select="/"/>
    <xsl:param name="element" select="."/>
    <xsl:param name="source" select="$element/@source"/>
    <xsl:param name="to"/>
    <xsl:variable name="value">
      <xsl:apply-templates select="($document//bt:source[starts-with($source, @uri)]/bt:mapping[@to = $to])[last()]" mode="mapping">
        <xsl:with-param name="element" select="$element"/>
      </xsl:apply-templates>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$value != ''">
        <xsl:value-of select="$value"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="schemaLocation">
          <xsl:for-each select="$document//*/@xsi:schemaLocation">
            <xsl:value-of select="."/>
            <xsl:text> </xsl:text>
          </xsl:for-each>
          <xsl:for-each select="$document/xs:schema/xs:*/@schemaLocation">
            <xsl:value-of select="."/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="."/>
            <xsl:text> </xsl:text>
          </xsl:for-each>
        </xsl:variable>        
        <xsl:call-template name="parseSchemaLocation">
          <xsl:with-param name="document" select="$document"/>
          <xsl:with-param name="element" select="$element"/>
          <xsl:with-param name="source" select="$source"/>
          <xsl:with-param name="to" select="$to"/>
          <xsl:with-param name="schemaLocation" select="substring-after(normalize-space($schemaLocation), ' ')"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="parseSchemaLocation">
    <xsl:param name="document" />
    <xsl:param name="element" />
    <xsl:param name="source" />
    <xsl:param name="to"/>
    <xsl:param name="schemaLocation"/>
    <xsl:choose>
      <xsl:when test="$schemaLocation = ''"/>
      <xsl:when test="contains($schemaLocation, ' ')">
        <xsl:variable name="value">
          <xsl:call-template name="mapSource">
            <xsl:with-param name="document" select="document(substring-before($schemaLocation, ' '), $document)"/>
            <xsl:with-param name="element" select="$element"/>
            <xsl:with-param name="source" select="$source"/>
            <xsl:with-param name="to" select="$to"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:choose>
          <xsl:when test="$value != ''">
            <xsl:value-of select="$value"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="parseSchemaLocation">
              <xsl:with-param name="document" select="$document"/>
              <xsl:with-param name="element" select="$element"/>
              <xsl:with-param name="source" select="$source"/>
              <xsl:with-param name="to" select="$to"/>
              <xsl:with-param name="schemaLocation" select="substring-after(substring-after($schemaLocation, ' '), ' ')"/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="mapSource">
          <xsl:with-param name="document" select="document($schemaLocation, $document)"/>
          <xsl:with-param name="element" select="$element"/>
          <xsl:with-param name="source" select="$source"/>
          <xsl:with-param name="to" select="$to"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="bt:mapping" mode="mapping">
    <xsl:param name="element"/>
    <xsl:apply-templates select="node()" mode="mapping">
      <xsl:with-param name="element" select="$element"/>
    </xsl:apply-templates>  
  </xsl:template>

  <xsl:template match="text()" mode="mapping">
    <xsl:copy/>
  </xsl:template>
  
  <xsl:template match="bt:attribute" mode="mapping">
    <xsl:param name="element"/>
    <xsl:choose>
      <xsl:when test="@namespace">
        <xsl:value-of select="string($element/@*[local-name(.) = current()/@name and namespace-uri(.) = current()/@namespace])"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="string($element/@*[local-name(.) = current()/@name and namespace-uri(.) = ''])"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
