Subject: Re: [xsl] XSLT 2 Functions for URL Manipulation (was Rewriting href) From: Eliot Kimber <ekimber@xxxxxxxxxxxx> Date: Sat, 28 Jun 2008 07:52:22 -0500 |
On 6/28/08 5:22 AM, "Marroc" <marrocdanderfluff@xxxxxxxxxxx> 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() < 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() < 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() < 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>
</xsl:text> <xsl:value-of select="."/> <xsl:text>

</xsl:text> </xsl:template> <xsl:template match="test" mode="testGetExtension"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> source: "</xsl:text><xsl:value-of select="source"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="test" mode="testGetNamePart"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> source: "</xsl:text><xsl:value-of select="source"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="test" mode="testGetName"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> source: "</xsl:text><xsl:value-of select="source"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="test" mode="testGetParent"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> source: "</xsl:text><xsl:value-of select="source"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="test" mode="testGetAbsolutePath"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> source: "</xsl:text><xsl:value-of select="source"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="test" mode="testGetRelativePath"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> source: "</xsl:text><xsl:value-of select="source"/><xsl:text>"
</xsl:text> <xsl:text> target: "</xsl:text><xsl:value-of select="target"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="test" mode="testEncodeUrl"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> source: "</xsl:text><xsl:value-of select="source"/><xsl:text>"
</xsl:text> <xsl:text> target: "</xsl:text><xsl:value-of select="target"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="test" mode="testNewFile"> <xsl:text>Test Case: </xsl:text><xsl:number count="test" format="[1]"/><xsl:text>
</xsl:text> <xsl:text> parent: "</xsl:text><xsl:value-of select="parent"/><xsl:text>"
</xsl:text> <xsl:text> child: "</xsl:text><xsl:value-of select="child"/><xsl:text>"
</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>
</xsl:text> <xsl:if test="not($pass)"> <xsl:text> expected result: "</xsl:text><xsl:value-of select="result"/><xsl:text>"
</xsl:text> </xsl:if> <xsl:copy-of select="comment"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> --- end of transform --- Cheers, Eliot ---- Eliot Kimber | Senior Solutions Architect | Really Strategies, Inc. email: ekimber@xxxxxxxxxxxx <mailto:ekimber@xxxxxxxxxxxx> 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>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Rewriting href, Marroc | Thread | RE: [xsl] Where is my document? loc, Marroc |
[xsl] Rewriting href, Marroc | Date | Re: [xsl] OOXML, Dimitre Novatchev |
Month |