xsl-list
[Top] [All Lists]

Re: [xsl] XSLT 2 Functions for URL Manipulation (was Rewriting href)

2008-06-28 05:53:23
On 6/28/08 5:22 AM, "Marroc" <marrocdanderfluff(_at_)yahoo(_dot_)co(_dot_)in> 
wrote:
 
Can anyone suggest an XSL technique or mechanism for taking either of these
types of dysfunctional path and making them into the shortest-possible
relative path? I think this demands that the XSLT is aware of the location
of the current document so that it can parse the folder path, decide where
it varies and rebuild it in a relative fashion.

Here is an XSLT 2 function package for working with paths, specifically
intended to solve the sort of URL rewriting problems you face (and in a DITA
context no less), and a set of unit tests for it.

--- cut here: relpath_util.xsl ---
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema";
  xmlns:local="http://www.example.com/functions/local";
  exclude-result-prefixes="local xs"
  
  >
  
  <xsl:function name="local:base-uri" as="xs:string">
    <xsl:param name="context" as="node()"/>
    <xsl:variable name="baseUri" select="string(base-uri($context))"
as="xs:string"/>
    <xsl:variable name="resultBaseUri"
      select="if (starts-with($baseUri, 'file:///'))
                 then (concat('file:/', substring-after($baseUri,
'file:///')))
                 else $baseUri
      " 
      as="xs:string"/>
    <xsl:sequence select="$resultBaseUri"/>
  </xsl:function>
  
  <xsl:function name="local:encodeUri" as="xs:string">
    <xsl:param name="inUriString" as="xs:string"/>
    <xsl:variable name="temp1" as="xs:string"
      select="replace($inUriString, ' ', '%20')"
    />
    <xsl:variable name="temp2" as="xs:string"
      select="replace($temp1, '\[', '%5B')"
    />
    <xsl:variable name="temp3" as="xs:string"
      select="replace($temp2, '\]', '%5D')"
    />
    <xsl:variable name="outUriString" as="xs:string"
      select="$temp3"
    />
    <xsl:sequence select="$outUriString"/>
  </xsl:function>
  
  <xsl:function name="local:getName" as="xs:string">
    <!-- As for Java File.getName(): returns the last
         component of the path.
    -->
    <xsl:param name="sourcePath" as="xs:string"/>
    <xsl:value-of select="tokenize($sourcePath, '/')[last()]"/>
  </xsl:function>
  
  <xsl:function name="local:getNamePart" as="xs:string">
    <!-- Returns the name part of a filename, excluding
         any trailing extension.
    -->
    <xsl:param name="sourcePath" as="xs:string"/>
    <xsl:variable name="fullName" select="local:getName($sourcePath)"
as="xs:string"/>
    <xsl:variable name="result" as="xs:string"
      select="if (contains($fullName, '.'))
                 then string-join(tokenize($fullName, '\.')[position() &lt;
last()], '.')
                 else $fullName
             "
    />
    <xsl:value-of select="$result"/>
  </xsl:function>
  
  <xsl:function name="local:getExtension" as="xs:string">
    <!-- Returns the extension part of a filename, excluding the
         leading "."
    -->
    <xsl:param name="sourcePath" as="xs:string"/>
    <xsl:variable name="fullName" select="local:getName($sourcePath)"
as="xs:string"/>
    <xsl:variable name="result" as="xs:string"
      select="if (contains($fullName, '.'))
      then tokenize($fullName, '\.')[last()]
      else ''
      "
    />
    <xsl:value-of select="$result"/>
  </xsl:function>
  
  <xsl:function name="local:getParent" as="xs:string">
    <!-- As for Java File.getParent(): returns all but the last
         components of the path.
    -->
    <xsl:param name="sourcePath" as="xs:string"/>
    <xsl:value-of select="string-join(tokenize($sourcePath, '/')[position()
&lt; last()], '/')"/>
  </xsl:function>
  
  <xsl:function name="local:newFile" as="xs:string">
    <!-- As for Java File(File, path)): Returns a new a absolute path
representing
         the new file. File must be a path (because XSLT has no way to
distinguish
         a file from a directory).
    -->
    <xsl:param name="parentPath" as="xs:string"/>
    <xsl:param name="childFile" as="xs:string"/>
    <xsl:choose>
      <xsl:when test="matches($childFile, '^(/|[a-z]+:)')">
        <xsl:value-of select="$childFile"/>
      </xsl:when>
      <xsl:when test="$parentPath = '/'">
        <xsl:variable name="tempPath" select="concat($parentPath,
$childFile)" as="xs:string"/>
        <xsl:variable name="result"
          select="local:getAbsolutePath($tempPath)"/>
        <xsl:value-of select="$result"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="tempParentPath" as="xs:string"
          select="if (ends-with($parentPath, '/') and $parentPath != '/')
          then substring($parentPath, 1, string-length($parentPath) - 1)
          else $parentPath" />
        <xsl:variable name="parentTokens" select="tokenize($tempParentPath,
'/')" as="xs:string*"/>
        <xsl:variable name="childTokens" select="tokenize($childFile, '/')"
as="xs:string*"/>
        <xsl:variable name="tempPath" select="string-join(($parentTokens,
$childTokens), '/')" as="xs:string"/>
        <xsl:variable name="result"
        select="local:getAbsolutePath($tempPath)"/>
        <xsl:value-of select="$result"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>
  
  <xsl:function name="local:getAbsolutePath" as="xs:string">
    <!-- Given a path resolves any ".." or "." terms to produce an absolute
path -->
    <xsl:param name="sourcePath" as="xs:string"/>
    <xsl:variable name="pathTokens" select="tokenize($sourcePath, '/')"
as="xs:string*"/>
    <xsl:if test="false()">
      <xsl:message> + DEBUG local:getAbsolutePath(): Starting</xsl:message>
      <xsl:message> +       sourcePath="<xsl:value-of
select="$sourcePath"/>"</xsl:message>
    </xsl:if>
    <xsl:variable name="baseResult"
    select="string-join(local:makePathAbsolute($pathTokens, ()), '/')"
as="xs:string"/>
    <xsl:variable name="baseResult2"
      select="if (ends-with($baseResult, '/'))
                 then substring($baseResult, 1, string-length($baseResult)
-1) 
                 else $baseResult" as="xs:string"/>
    <xsl:variable name="result" as="xs:string"
       select="if (starts-with($sourcePath, '/') and
not(starts-with($baseResult2, '/')))
                  then concat('/', $baseResult2)
                  else $baseResult2
               "
    />
    <xsl:if test="false()">
      <xsl:message> + DEBUG: result="<xsl:value-of
select="$result"/>"</xsl:message>
    </xsl:if>
    <xsl:value-of select="$result"/>
  </xsl:function>
  
  <xsl:function name="local:makePathAbsolute" as="xs:string*">
    <xsl:param name="pathTokens" as="xs:string*"/>
    <xsl:param name="resultTokens" as="xs:string*"/>
    <xsl:if test="false()">
      <xsl:message> + DEBUG: local:makePathAbsolute():
Starting...</xsl:message>
      <xsl:message> + DEBUG:    pathTokens="<xsl:value-of
select="string-join($pathTokens, ',')"/>"</xsl:message>
      <xsl:message> + DEBUG:    resultTokens="<xsl:value-of
select="string-join($resultTokens, ',')"/>"</xsl:message>
    </xsl:if>
    <xsl:sequence select="if (count($pathTokens) = 0)
                             then $resultTokens
                             else if ($pathTokens[1] = '.')
                                  then
local:makePathAbsolute($pathTokens[position() > 1], $resultTokens)
                                  else if ($pathTokens[1] = '..')
                                       then
local:makePathAbsolute($pathTokens[position() > 1], $resultTokens[position()
&lt; last()])
                                       else
local:makePathAbsolute($pathTokens[position() > 1], ($resultTokens,
$pathTokens[1]))
                         "/>
  </xsl:function>
  
  <xsl:function name="local:getRelativePath" as="xs:string">
<!-- Calculate relative path that gets from from source path to target path.
  
  Given:
  
  [1]  Target: /A/B/C
     Source: /A/B/C/X
  
  Return: "X"
  
  [2]  Target: /A/B/C
       Source: /E/F/G/X
  
  Return: "/E/F/G/X"
    
  [3]  Target: /A/B/C
       Source: /A/D/E/X
  
  Return: "../../D/E/X"
  
  [4]  Target: /A/B/C
       Source: /A/X
  
  Return: "../../X"
  
  
-->
  
    <xsl:param name="source" as="xs:string"/><!-- Path to get relative path
*from* -->
    <xsl:param name="target" as="xs:string"/><!-- Path to get relataive path
*to* -->
    <xsl:if test="false()">
      <xsl:message> + DEBUG: local:getRelativePath():
Starting...</xsl:message>
      <xsl:message> + DEBUG:     source="<xsl:value-of
select="$source"/>"</xsl:message>
      <xsl:message> + DEBUG:     target="<xsl:value-of
select="$target"/>"</xsl:message>
    </xsl:if>
    <xsl:variable name="sourceTokens" select="tokenize((if
(starts-with($source, '/')) then substring-after($source, '/') else
$source), '/')" as="xs:string*"/>
    <xsl:variable name="targetTokens" select="tokenize((if
(starts-with($target, '/')) then substring-after($target, '/') else
$target), '/')" as="xs:string*"/>
    <xsl:choose>
      <xsl:when test="(count($sourceTokens) > 0 and count($targetTokens) >
0) and 
                      (($sourceTokens[1] != $targetTokens[1]) and
                       (contains($sourceTokens[1], ':') or
contains($targetTokens[1], ':')))">
        <!-- Must be absolute URLs with different schemes, cannot be
relative, return
        target as is. -->
        <xsl:value-of select="$target"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="resultTokens"
          select="local:analyzePathTokens($sourceTokens, $targetTokens, ())"
as="xs:string*"/>  
        <xsl:variable name="result" select="string-join($resultTokens, '/')"
as="xs:string"/>
        <xsl:value-of select="$result"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>
  
  <xsl:function name="local:analyzePathTokens" as="xs:string*">
    <xsl:param name="sourceTokens" as="xs:string*"/>
    <xsl:param name="targetTokens" as="xs:string*"/>
    <xsl:param name="resultTokens" as="xs:string*"/>
    <xsl:if test="false()">
    <xsl:message> + DEBUG: local:analyzePathTokens():
Starting...</xsl:message>
    <xsl:message> + DEBUG:     sourceTokens=<xsl:value-of
select="string-join($sourceTokens, ',')"/></xsl:message>
    <xsl:message> + DEBUG:     targetTokens=<xsl:value-of
select="string-join($targetTokens, ',')"/></xsl:message>
    <xsl:message> + DEBUG:     resultTokens=<xsl:value-of
select="string-join($resultTokens, ',')"/></xsl:message>
    </xsl:if>
    <xsl:choose>
      <xsl:when test="count($sourceTokens) = 0">
        <!-- Append remaining target tokens (if any) to the result -->
        <xsl:sequence select="$resultTokens, $targetTokens"/>
      </xsl:when>
      <xsl:otherwise>
        <!-- Still source tokens, so see if source[1] = target[1] -->
        <xsl:choose>
          <!-- If they are equal, go to the next level in the paths: -->
          <xsl:when test="(count($targetTokens) > 0) and ($sourceTokens[1] =
$targetTokens[1])">
            <xsl:sequence
select="local:analyzePathTokens($sourceTokens[position() > 1],
$targetTokens[position() > 1], $resultTokens)"/>
          </xsl:when>
          <xsl:otherwise>
            <!-- Paths must diverge at this point. Append one ".." for each
token
            left in the source: -->
            <xsl:variable name="goUps" as="xs:string*">
              <xsl:for-each select="$sourceTokens">
                <xsl:sequence select="'..'"/>
              </xsl:for-each>
            </xsl:variable>
            <xsl:sequence select="string-join(($resultTokens, $goUps,
$targetTokens), '/')"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>  
  </xsl:function>
</xsl:stylesheet>
--- cut here: relpath_util_test.xsl: ---
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema";
  xmlns:local="http://www.example.com/functions/local";
  exclude-result-prefixes="local xs"
  >
  
  <xsl:include href="../../ldist/xslt/relpath_util.xsl"/>
  
<!-- Tests for the relpath_util functions
-->
  
    
  
  <xsl:template match="/">
<!--    <xsl:call-template name="testEncodeUrl"/>
    <xsl:call-template name="testGetAbsolutePath"/>
-->    <xsl:call-template name="testGetRelativePath"/>
<!--    <xsl:call-template name="testGetName"/>
    <xsl:call-template name="testGetParent"/>
    <xsl:call-template name="testNewFile"/>
    <xsl:call-template name="testGetNamePart"/>
    <xsl:call-template name="testGetExtension"/>
-->  </xsl:template>
  
  <xsl:template name="testEncodeUrl">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>encodeUrl() Tests</title>
        <test>
          <source>/</source>
          <result>/</result>
        </test>
        <test>
          <source>/A B/C</source>
          <result>/A%20B/C</result>
        </test>
        <test>
          <source>/A[B]/D/foo.bar#e</source>
          <result>/A%5BB%5D/D/foo.bar#e</result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testEncodeUrl"/>
  </xsl:template>
  
  <xsl:template name="testGetAbsolutePath">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>getAbsolutePath() Tests</title>
        <test>
          <source>/</source>
          <result>/</result>
        </test>
        <test>
          <source>/A</source>
          <result>/A</result>
        </test>
        <test>
          <source>/A/..</source>
          <result>/</result>
        </test>
        <test>
          <source>/A/./B</source>
          <result>/A/B</result>
        </test>
        <test>
          <source>/A/B/C/D/../../E</source>
          <result>/A/B/E</result>
        </test>
        <test>
          <source>/A/B/C/D/../../E/F</source>
          <result>/A/B/E/F</result>
        </test>
        <test>
          <source>file:///A/B/C</source>
          <result>file:///A/B/C</result>
        </test>
        <test>
          <source>./A/B/C/D/E.xml</source>
          <result>A/B/C/D/E.xml</result>
        </test>
        <test>
          <source>/A/B/</source>
          <result>/A/B</result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testGetAbsolutePath"/>
  </xsl:template>
  
  <xsl:template name="testGetRelativePath">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>getRelativePath() Tests</title>
        <test>
          <source>/</source>
          <target>/A</target>
          <result>A</result>
        </test>
        <test>
          <source>/A</source>
          <target>/</target>
          <result>..</result>
        </test>
        <test>
          <source>/A</source>
          <target>/B</target>
          <result>../B</result>
        </test>
        <test>
          <source>/A</source>
          <target>/A/B</target>
          <result>B</result>
        </test>
        <test>
          <source>/A/B/C/D</source>
          <target>/A</target>
          <result>../../..</result>
        </test>
        <test>
          <source>/A/B/C/Z/Y</source>
          <target>/A/B/C/Y/Z</target>
          <result>../../Y/Z</result>
        </test>
        <test>
          <source>/A/B/C/D</source>
          <target>/A/E</target>
          <result>../../../E</result>
        </test>
        <test>
          <source>/A/B/C/D.xml</source>
          <target>/A/E</target>
          <result>../../E</result>
          <comment>This test should fail because there's no way for the XSLT
            to know that D.xml is a file and not a directory.
            The source parameter to relpath must be a directory path,
            not a filename.</comment>
        </test>
        <test>
          <source>/A/B</source>
          <target>/A/C/D</target>
          <result>../C/D</result>
        </test>
        <test>
          <source>/A/B/C</source>
          <target>/A/B/C/D/E</target>
          <result>D/E</result>
        </test>
        <test>
          <source>file:///A/B/C</source>
          <target>http://A/B/C/D/E</target>
          <result>http://A/B/C/D/E</result>
        </test>
        <test>
          <source>file://A/B/C</source>
          <target>file://A/B/C/D/E.xml</target>
          <result>D/E.xml</result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testGetRelativePath"/>
  </xsl:template>
  
  <xsl:template match="test_data" mode="#all">
    <test_results>
      <xsl:apply-templates mode="#current"/>
    </test_results>
  </xsl:template>
  
  <xsl:template name="testGetName">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>getName() Tests</title>
        <test>
          <source>/</source>
          <result></result>
        </test>
        <test>
          <source>/A</source>
          <result>A</result>
        </test>
        <test>
          <source>/A/B</source>
          <result>B</result>
        </test>
        <test>
          <source>/A/B/C/D</source>
          <result>D</result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testGetName"/>
  </xsl:template>
  
  <xsl:template name="testGetParent">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>getParent() Tests</title>
        <test>
          <source>/</source>
          <result></result>
        </test>
        <test>
          <source>/A</source>
          <result></result>
        </test>
        <test>
          <source>/A/B</source>
          <result>/A</result>
        </test>
        <test>
          <source>/A/B/C/D</source>
          <result>/A/B/C</result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testGetParent"/>
  </xsl:template>
  
  <xsl:template name="testNewFile">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>newFile() Tests</title>
        <test>
          <parent>/</parent>
          <child>A</child>
          <result>/A</result>
        </test>
        <test>
          <parent>/A/B</parent>
          <child>C</child>
          <result>/A/B/C</result>
        </test>
        <test>
          <parent>/A/B</parent>
          <child>file://C</child>
          <result>file://C</result>
        </test>
        <test>
          <parent>/A/B</parent>
          <child>/C</child>
          <result>/C</result>
        </test>
        <test>
          <parent>/A/B</parent>
          <child>../C</child>
          <result>/A/C</result>
        </test>
        <test>
          <parent>/A/B</parent>
          <child>./C</child>
          <result>/A/B/C</result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testNewFile"/>
  </xsl:template>
  
  <xsl:template name="testGetNamePart">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>getNamePart() Tests</title>
        <test>
          <source>/</source>
          <result></result>
        </test>
        <test>
          <source>/A/B</source>
          <result>B</result>
        </test>
        <test>
          <source>/A/B/C.xml</source>
          <result>C</result>
        </test>
        <test>
          <source>/A/B/thisisalongname.foo</source>
          <result>thisisalongname</result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testGetNamePart"/>
  </xsl:template>
  
  <xsl:template name="testGetExtension">
    <xsl:variable name="testData" as="element()">
      <test_data>
        <title>getExtension() Tests</title>
        <test>
          <source>/</source>
          <result></result>
        </test>
        <test>
          <source>/A/B</source>
          <result></result>
        </test>
        <test>
          <source>/A/B/C.xml</source>
          <result>xml</result>
        </test>
        <test>
          <source>/A/B/thisisalongname.foo</source>
          <result>foo</result>
        </test>
        <test>
          <source>/A/B/CCCC.</source>
          <result></result>
        </test>
      </test_data>
    </xsl:variable>
    <xsl:apply-templates select="$testData" mode="testGetExtension"/>
  </xsl:template>
  <xsl:template match="title" mode="#all">
    <xsl:text>&#x0a;</xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>&#x0a;&#x0a;</xsl:text>
  </xsl:template>
  
  <xsl:template match="test" mode="testGetExtension">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      source: "</xsl:text><xsl:value-of
select="source"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:getExtension(string(source))"
as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>
  
  <xsl:template match="test" mode="testGetNamePart">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      source: "</xsl:text><xsl:value-of
select="source"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:getNamePart(string(source))"
as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>
  
  <xsl:template match="test" mode="testGetName">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      source: "</xsl:text><xsl:value-of
select="source"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:getName(string(source))"
as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>
  
  <xsl:template match="test" mode="testGetParent">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      source: "</xsl:text><xsl:value-of
select="source"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:getParent(string(source))"
as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>
  
  <xsl:template match="test" mode="testGetAbsolutePath">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      source: "</xsl:text><xsl:value-of
select="source"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:getAbsolutePath(string(source))"
as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>
  
  <xsl:template match="test" mode="testGetRelativePath">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      source: "</xsl:text><xsl:value-of
select="source"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:text>      target: "</xsl:text><xsl:value-of
select="target"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:getRelativePath(string(source),
string(target))" as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>

  <xsl:template match="test" mode="testEncodeUrl">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      source: "</xsl:text><xsl:value-of
select="source"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:text>      target: "</xsl:text><xsl:value-of
select="target"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:encodeUri(string(source))"
as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>
  
  <xsl:template match="test" mode="testNewFile">
    <xsl:text>Test Case: </xsl:text><xsl:number count="test"
format="[1]"/><xsl:text>&#x0a;</xsl:text>
    <xsl:text>      parent: "</xsl:text><xsl:value-of
select="parent"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:text>      child: "</xsl:text><xsl:value-of
select="child"/><xsl:text>"&#x0a;</xsl:text>
    <xsl:variable name="cand" select="local:newFile(string(parent),
string(child))" as="xs:string"/>
    <xsl:variable name="pass" select="$cand = string(result)"
as="xs:boolean"/>
    <xsl:text>      result: "</xsl:text><xsl:value-of
select="$cand"/><xsl:text>", pass: </xsl:text><xsl:value-of
select="$pass"/><xsl:text>&#x0a;</xsl:text>
    <xsl:if test="not($pass)">
      <xsl:text>      expected result: "</xsl:text><xsl:value-of
select="result"/><xsl:text>"&#x0a;</xsl:text>
    </xsl:if>
    <xsl:copy-of select="comment"/>
    <xsl:text>&#x0a;</xsl:text>
  </xsl:template>
</xsl:stylesheet>
--- end of transform ---

Cheers,

Eliot

----
Eliot Kimber | Senior Solutions Architect | Really Strategies, Inc.
email:  ekimber(_at_)reallysi(_dot_)com <mailto:ekimber(_at_)reallysi(_dot_)com>
office: 610.631.6770 | cell: 512.554.9368
2570 Boulevard of the Generals | Suite 213 | Audubon, PA 19403
www.reallysi.com <http://www.reallysi.com>  | http://blog.reallysi.com
<http://blog.reallysi.com> | www.rsuitecms.com <http://www.rsuitecms.com> 


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--