| <?xml version="1.0"?> |
| |
| <xsl:stylesheet |
| version="1.0" |
| extension-element-prefixes="doc" |
| xmlns:xsl="http://www.w3.org/1999/XSL/Transform" |
| xmlns:doc="http://xsltsl.org/xsl/documentation/1.0" |
| xmlns:uri="http://xsltsl.org/uri" |
| > |
| |
| <doc:reference xmlns=""> |
| <referenceinfo> |
| <releaseinfo role="meta"> |
| $Id$ |
| </releaseinfo> |
| <author> |
| <surname>Diamond</surname> |
| <firstname>Jason</firstname> |
| </author> |
| <copyright> |
| <year>2001</year> |
| <holder>Jason Diamond</holder> |
| </copyright> |
| </referenceinfo> |
| |
| <title>URI (Uniform Resource Identifier) Processing</title> |
| |
| <partintro> |
| <section> |
| <title>Introduction</title> |
| <para>This module provides templates for processing URIs (Uniform Resource Identifers).</para> |
| </section> |
| </partintro> |
| |
| </doc:reference> |
| |
| <doc:template name="uri:is-absolute-uri" xmlns=""> |
| <refpurpose>Determines if a URI is absolute or relative.</refpurpose> |
| |
| <refdescription> |
| <para>Absolute URIs start with a scheme (like "http:" or "mailto:").</para> |
| </refdescription> |
| |
| <refparameter> |
| <variablelist> |
| <varlistentry> |
| <term>uri</term> |
| <listitem> |
| <para>An absolute or relative URI.</para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refparameter> |
| |
| <refreturn> |
| <para>Returns 'true' if the URI is absolute or '' if it's not.</para> |
| </refreturn> |
| </doc:template> |
| |
| <xsl:template name="uri:is-absolute-uri"> |
| <xsl:param name="uri"/> |
| |
| <xsl:if test="contains($uri, ':')"> |
| <xsl:value-of select="true()"/> |
| </xsl:if> |
| |
| </xsl:template> |
| |
| <doc:template name="uri:get-uri-scheme" xmlns=""> |
| <refpurpose>Gets the scheme part of a URI.</refpurpose> |
| |
| <refdescription> |
| <para>The ':' is not part of the scheme.</para> |
| </refdescription> |
| |
| <refparameter> |
| <variablelist> |
| <varlistentry> |
| <term>uri</term> |
| <listitem> |
| <para>An absolute or relative URI.</para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refparameter> |
| |
| <refreturn> |
| <para>Returns the scheme (without the ':') or '' if the URI is relative.</para> |
| </refreturn> |
| </doc:template> |
| |
| <xsl:template name="uri:get-uri-scheme"> |
| <xsl:param name="uri"/> |
| <xsl:if test="contains($uri, ':')"> |
| <xsl:value-of select="substring-before($uri, ':')"/> |
| </xsl:if> |
| </xsl:template> |
| |
| <doc:template name="uri:get-uri-authority" xmlns=""> |
| <refpurpose>Gets the authority part of a URI.</refpurpose> |
| |
| <refdescription> |
| <para>The authority usually specifies the host machine for a resource. It always follows '//' in a typical URI.</para> |
| </refdescription> |
| |
| <refparameter> |
| <variablelist> |
| <varlistentry> |
| <term>uri</term> |
| <listitem> |
| <para>An absolute or relative URI.</para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refparameter> |
| |
| <refreturn> |
| <para>Returns the authority (without the '//') or '' if the URI has no authority.</para> |
| </refreturn> |
| </doc:template> |
| |
| <xsl:template name="uri:get-uri-authority"> |
| <xsl:param name="uri"/> |
| |
| <xsl:variable name="a"> |
| <xsl:choose> |
| <xsl:when test="contains($uri, ':')"> |
| <xsl:if test="substring(substring-after($uri, ':'), 1, 2) = '//'"> |
| <xsl:value-of select="substring(substring-after($uri, ':'), 3)"/> |
| </xsl:if> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:if test="substring($uri, 1, 2) = '//'"> |
| <xsl:value-of select="substring($uri, 3)"/> |
| </xsl:if> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:variable> |
| |
| <xsl:choose> |
| <xsl:when test="contains($a, '/')"> |
| <xsl:value-of select="substring-before($a, '/')" /> |
| </xsl:when> |
| <xsl:when test="contains($a, '?')"> |
| <xsl:value-of select="substring-before($a, '?')" /> |
| </xsl:when> |
| <xsl:when test="contains($a, '#')"> |
| <xsl:value-of select="substring-before($a, '#')" /> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$a" /> |
| </xsl:otherwise> |
| </xsl:choose> |
| |
| </xsl:template> |
| |
| <doc:template name="uri:get-uri-path" xmlns=""> |
| <refpurpose>Gets the path part of a URI.</refpurpose> |
| |
| <refdescription> |
| <para>The path usually comes after the '/' in a URI.</para> |
| </refdescription> |
| |
| <refparameter> |
| <variablelist> |
| <varlistentry> |
| <term>uri</term> |
| <listitem> |
| <para>An absolute or relative URI.</para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refparameter> |
| |
| <refreturn> |
| <para>Returns the path (with any leading '/') or '' if the URI has no path.</para> |
| </refreturn> |
| </doc:template> |
| |
| <xsl:template name="uri:get-uri-path"> |
| <xsl:param name="uri"/> |
| |
| <xsl:variable name="p"> |
| <xsl:choose> |
| <xsl:when test="contains($uri, '//')"> |
| <xsl:if test="contains(substring-after($uri, '//'), '/')"> |
| <xsl:value-of select="concat('/', substring-after(substring-after($uri, '//'), '/'))"/> |
| </xsl:if> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:choose> |
| <xsl:when test="contains($uri, ':')"> |
| <xsl:value-of select="substring-after($uri, ':')"/> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$uri"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:variable> |
| |
| <xsl:choose> |
| <xsl:when test="contains($p, '?')"> |
| <xsl:value-of select="substring-before($p, '?')" /> |
| </xsl:when> |
| <xsl:when test="contains($p, '#')"> |
| <xsl:value-of select="substring-before($p, '#')" /> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$p" /> |
| </xsl:otherwise> |
| </xsl:choose> |
| |
| </xsl:template> |
| |
| <doc:template name="uri:get-uri-query" xmlns=""> |
| <refpurpose>Gets the query part of a URI.</refpurpose> |
| |
| <refdescription> |
| <para>The query comes after the '?' in a URI.</para> |
| </refdescription> |
| |
| <refparameter> |
| <variablelist> |
| <varlistentry> |
| <term>uri</term> |
| <listitem> |
| <para>An absolute or relative URI.</para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refparameter> |
| |
| <refreturn> |
| <para>Returns the query (without the '?') or '' if the URI has no query.</para> |
| </refreturn> |
| </doc:template> |
| |
| <xsl:template name="uri:get-uri-query"> |
| <xsl:param name="uri"/> |
| |
| <xsl:variable name="q" select="substring-after($uri, '?')"/> |
| |
| <xsl:choose> |
| <xsl:when test="contains($q, '#')"> |
| <xsl:value-of select="substring-before($q, '#')"/> |
| </xsl:when> |
| <xsl:otherwise><xsl:value-of select="$q"/></xsl:otherwise> |
| </xsl:choose> |
| |
| </xsl:template> |
| |
| <doc:template name="uri:get-uri-fragment" xmlns=""> |
| <refpurpose>Gets the fragment part of a URI.</refpurpose> |
| |
| <refdescription> |
| <para>The fragment comes after the '#' in a URI.</para> |
| </refdescription> |
| |
| <refparameter> |
| <variablelist> |
| <varlistentry> |
| <term>uri</term> |
| <listitem> |
| <para>An absolute or relative URI.</para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refparameter> |
| |
| <refreturn> |
| <para>Returns the fragment (without the '#') or '' if the URI has no fragment.</para> |
| </refreturn> |
| </doc:template> |
| |
| <xsl:template name="uri:get-uri-fragment"> |
| <xsl:param name="uri"/> |
| |
| <xsl:value-of select="substring-after($uri, '#')"/> |
| |
| </xsl:template> |
| |
| <doc:template name="uri:resolve-uri" xmlns=""> |
| <refpurpose>Resolves a URI reference against a base URI.</refpurpose> |
| |
| <refdescription> |
| <para>This template follows the guidelines specified by <ulink url="ftp://ftp.isi.edu/in-notes/rfc2396.txt">RFC 2396</ulink>.</para> |
| </refdescription> |
| |
| <refparameter> |
| <variablelist> |
| <varlistentry> |
| <term>reference</term> |
| <listitem> |
| <para>A (potentially relative) URI reference.</para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>base</term> |
| <listitem> |
| <para>The base URI.</para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>document</term> |
| <listitem> |
| <para>The URI of the current document. This defaults to the value of the base URI if not specified.</para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refparameter> |
| |
| <refreturn> |
| <para>The "combined" URI.</para> |
| </refreturn> |
| </doc:template> |
| |
| <xsl:template name="uri:resolve-uri"> |
| <xsl:param name="reference"/> |
| <xsl:param name="base"/> |
| <xsl:param name="document" select="$base"/> |
| |
| <xsl:variable name="reference-scheme"> |
| <xsl:call-template name="uri:get-uri-scheme"> |
| <xsl:with-param name="uri" select="$reference"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="reference-authority"> |
| <xsl:call-template name="uri:get-uri-authority"> |
| <xsl:with-param name="uri" select="$reference"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="reference-path"> |
| <xsl:call-template name="uri:get-uri-path"> |
| <xsl:with-param name="uri" select="$reference"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="reference-query"> |
| <xsl:call-template name="uri:get-uri-query"> |
| <xsl:with-param name="uri" select="$reference"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="reference-fragment"> |
| <xsl:call-template name="uri:get-uri-fragment"> |
| <xsl:with-param name="uri" select="$reference"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:choose> |
| |
| <xsl:when test=" |
| not(string-length($reference-scheme)) and |
| not(string-length($reference-authority)) and |
| not(string-length($reference-path)) and |
| not(string-length($reference-query))" |
| > |
| |
| <xsl:choose> |
| <xsl:when test="contains($document, '?')"> |
| <xsl:value-of select="substring-before($document, '?')"/> |
| </xsl:when> |
| <xsl:when test="contains($document, '#')"> |
| <xsl:value-of select="substring-before($document, '#')"/> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$document"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| |
| <xsl:if test="string-length($reference-fragment)"> |
| <xsl:value-of select="concat('#', $reference-fragment)"/> |
| </xsl:if> |
| |
| </xsl:when> |
| |
| <xsl:when test="string-length($reference-scheme)"> |
| |
| <xsl:value-of select="$reference"/> |
| |
| </xsl:when> |
| |
| <xsl:otherwise> |
| |
| <xsl:variable name="base-scheme"> |
| <xsl:call-template name="uri:get-uri-scheme"> |
| <xsl:with-param name="uri" select="$base"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="base-authority"> |
| <xsl:call-template name="uri:get-uri-authority"> |
| <xsl:with-param name="uri" select="$base"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="base-path"> |
| <xsl:call-template name="uri:get-uri-path"> |
| <xsl:with-param name="uri" select="$base"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="base-query"> |
| <xsl:call-template name="uri:get-uri-query"> |
| <xsl:with-param name="uri" select="$base"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="base-fragment"> |
| <xsl:call-template name="uri:get-uri-fragment"> |
| <xsl:with-param name="uri" select="$base"/> |
| </xsl:call-template> |
| </xsl:variable> |
| |
| <xsl:variable name="result-authority"> |
| <xsl:choose> |
| <xsl:when test="string-length($reference-authority)"> |
| <xsl:value-of select="$reference-authority"/> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$base-authority"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:variable> |
| |
| <xsl:variable name="result-path"> |
| <xsl:choose> |
| <!-- don't normalize absolute paths --> |
| <xsl:when test="starts-with($reference-path, '/')"> |
| <xsl:value-of select="$reference-path" /> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:call-template name="uri:normalize-path"> |
| <xsl:with-param name="path"> |
| <xsl:if test="string-length($reference-authority) = 0 and substring($reference-path, 1, 1) != '/'"> |
| <xsl:call-template name="uri:get-path-without-file"> |
| <xsl:with-param name="path-with-file" select="$base-path"/> |
| </xsl:call-template> |
| <xsl:value-of select="'/'"/> |
| </xsl:if> |
| <xsl:value-of select="$reference-path"/> |
| </xsl:with-param> |
| </xsl:call-template> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:variable> |
| |
| <xsl:value-of select="concat($base-scheme, '://', $result-authority, $result-path)"/> |
| |
| <xsl:if test="string-length($reference-query)"> |
| <xsl:value-of select="concat('?', $reference-query)"/> |
| </xsl:if> |
| |
| <xsl:if test="string-length($reference-fragment)"> |
| <xsl:value-of select="concat('#', $reference-fragment)"/> |
| </xsl:if> |
| |
| </xsl:otherwise> |
| </xsl:choose> |
| |
| </xsl:template> |
| |
| <xsl:template name="uri:get-path-without-file"> |
| <xsl:param name="path-with-file" /> |
| <xsl:param name="path-without-file" /> |
| |
| <xsl:choose> |
| <xsl:when test="contains($path-with-file, '/')"> |
| <xsl:call-template name="uri:get-path-without-file"> |
| <xsl:with-param name="path-with-file" select="substring-after($path-with-file, '/')" /> |
| <xsl:with-param name="path-without-file"> |
| <xsl:choose> |
| <xsl:when test="$path-without-file"> |
| <xsl:value-of select="concat($path-without-file, '/', substring-before($path-with-file, '/'))" /> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="substring-before($path-with-file, '/')" /> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:with-param> |
| </xsl:call-template> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$path-without-file" /> |
| </xsl:otherwise> |
| </xsl:choose> |
| |
| </xsl:template> |
| |
| <xsl:template name="uri:normalize-path"> |
| <xsl:param name="path"/> |
| <xsl:param name="result" select="''"/> |
| |
| <xsl:choose> |
| <xsl:when test="string-length($path)"> |
| <xsl:choose> |
| <xsl:when test="$path = '/'"> |
| <xsl:value-of select="concat($result, '/')"/> |
| </xsl:when> |
| <xsl:when test="$path = '.'"> |
| <xsl:value-of select="concat($result, '/')"/> |
| </xsl:when> |
| <xsl:when test="$path = '..'"> |
| <xsl:call-template name="uri:get-path-without-file"> |
| <xsl:with-param name="path-with-file" select="$result"/> |
| </xsl:call-template> |
| <xsl:value-of select="'/'"/> |
| </xsl:when> |
| <xsl:when test="contains($path, '/')"> |
| <!-- the current segment --> |
| <xsl:variable name="s" select="substring-before($path, '/')"/> |
| <!-- the remaining path --> |
| <xsl:variable name="p"> |
| <xsl:choose> |
| <xsl:when test="substring-after($path, '/') = ''"> |
| <xsl:value-of select="'/'"/> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="substring-after($path, '/')"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:variable> |
| <xsl:choose> |
| <xsl:when test="$s = ''"> |
| <xsl:call-template name="uri:normalize-path"> |
| <xsl:with-param name="path" select="$p"/> |
| <xsl:with-param name="result" select="$result"/> |
| </xsl:call-template> |
| </xsl:when> |
| <xsl:when test="$s = '.'"> |
| <xsl:call-template name="uri:normalize-path"> |
| <xsl:with-param name="path" select="$p"/> |
| <xsl:with-param name="result" select="$result"/> |
| </xsl:call-template> |
| </xsl:when> |
| <xsl:when test="$s = '..'"> |
| <xsl:choose> |
| <xsl:when test="string-length($result) and (substring($result, string-length($result) - 2) != '/..')"> |
| <xsl:call-template name="uri:normalize-path"> |
| <xsl:with-param name="path" select="$p"/> |
| <xsl:with-param name="result"> |
| <xsl:call-template name="uri:get-path-without-file"> |
| <xsl:with-param name="path-with-file" select="$result"/> |
| </xsl:call-template> |
| </xsl:with-param> |
| </xsl:call-template> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:call-template name="uri:normalize-path"> |
| <xsl:with-param name="path" select="$p"/> |
| <xsl:with-param name="result" select="concat($result, '/..')"/> |
| </xsl:call-template> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:call-template name="uri:normalize-path"> |
| <xsl:with-param name="path" select="$p"/> |
| <xsl:with-param name="result" select="concat($result, '/', $s)"/> |
| </xsl:call-template> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="concat($result, '/', $path)"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| </xsl:when> |
| <xsl:otherwise> |
| <xsl:value-of select="$result"/> |
| </xsl:otherwise> |
| </xsl:choose> |
| |
| </xsl:template> |
| |
| </xsl:stylesheet> |