0
如何將URI相對化爲另一個URI?XQuery中的URI相對化
URI1
file:/folder1/file2.txt
URI2
file:/folder1/folder2/file1.txt
需要的結果
relativize-method($uri1, $uri2) == '../file2.txt'
如何將URI相對化爲另一個URI?XQuery中的URI相對化
URI1
file:/folder1/file2.txt
URI2
file:/folder1/folder2/file1.txt
需要的結果
relativize-method($uri1, $uri2) == '../file2.txt'
像這樣(將重寫它XQuery中):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:sequence select="my:RelativeUrl(url[1], url[2])"/>
</xsl:template>
<xsl:function name="my:RelativeUrl" as="xs:string">
<xsl:param name="pUrl" as="xs:string"/>
<xsl:param name="pBase" as="xs:string"/>
<xsl:variable name="vurlSegments" select="tokenize($pUrl, '/')"/>
<xsl:variable name="vbaseSegments" select="tokenize($pBase, '/')"/>
<xsl:variable name="vCommonPrefixLength" select=
"(for $i in 1 to count($vbaseSegments)
return
if($vbaseSegments[$i] ne $vurlSegments[$i])
then $i -1
else()
)[1]
"/>
<xsl:variable name="vUpSteps" select=
"count($vbaseSegments) -$vCommonPrefixLength "/>
<xsl:sequence select=
"string-join
(
(
(for $i in 1 to $vUpSteps
return
'..'
),
(for $k in 1 to count($vurlSegments) - $vCommonPrefixLength
return
$vurlSegments[$vCommonPrefixLength + $k]
)
),
'/'
)
"/>
</xsl:function>
</xsl:stylesheet>
當此XML文檔上施加:
<t>
<url>file:/folder1/file2.txt</url>
<url>file:/folder1/folder2/file1.txt</url>
</t>
想要的,正確的結果產生:
../../file2.txt
你可以記號化得到的目錄,然後使用遞歸函數來計算期望的結果。像下面(上try.zorba-xquery.com測試):
declare function local:compute-relative-uri($absolute as xs:string,
$current as xs:string)
{
local:compute-relative-uri-aux(tokenize($absolute, "/"),
tokenize($current, "/"))
};
declare function local:compute-relative-uri-aux($absolute as xs:string*,
$current as xs:string*)
{
if (head($absolute) eq head($current))
then
local:compute-relative-uri-aux(tail($absolute), tail($current))
else
let $steps := (for $dir in 1 to count($current) - 1 return "..", $absolute)
return string-join($steps, "/")
};
let $absolute := "file:/folder1/file2.txt"
let $current := "file:/folder1/folder2/file1.txt"
return
local:compute-relative-uri($absolute, $current)