This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: xslt strings: 'substring-between'?
- To: xsl-list at mulberrytech dot com
- Subject: Re: xslt strings: 'substring-between'?
- From: Richard Light <richard at light dot demon dot co dot uk>
- Date: Wed, 2 Aug 2000 09:32:53 +0100
- References: <39870F57.40C29FDA@gte.com>
- Reply-To: xsl-list at mulberrytech dot com
In message <39870F57.40C29FDA@gte.com>, Steve Morrison
<smorrison@gte.com> writes
>
>I want to be able to parse an url string, and return name value pairs:
>page.cgi?T=boston&S=MA
>I can test if the T parameter exists and has a value (not equal to &), but, how
>do I extract the contents between the = and the next &? e.g. "boston"?
>What if there isn't a trailing & on the parameter (the last parameter in the
>url, such as S=MA above)?
>
>I have an <url> tag on each page which references the current document (such cgi
>environment variables) and I want to be able to extract it's contents without
>knowing beforehand what the contents may look like.
You can put together templates to do this kind of work, using the built-
in string manipulation functions and recursive template calls. Opening
Mike Kay's book (more or less) at random, I found an example of this
recursive technique on p.518-9.
In this case, you would use the characters '?', '=' and '&' ('&') as
markers.
To get the effect of 'substring-between', you can nest substring
commands, e.g.:
substring-before(substring-after($parameterString, '='), '&')
returns the portion of the string between '=' and '&'.
As you say, this won't work if you don't have an '&' in the [remainder
of the] string, so you need an <xsl:choose>, with a test that the string
to be processed contains this character:
<xsl:choose>
<xsl:when test="contains($parameterString, '&')">
... instruction that assumes presence of '&' ...
</xsl:when>
<xsl:otherwise>
... instruction that assumes absence of '&' ...
</xsl:otherwise>
</xsl:choose>
Assuming that you want to find the value for a specific name, you could
do something like this:
<xsl:template name="getParameterValue">
<xsl:param name="parameterName"/>
<xsl:param name="parameterString"/>
<xsl:choose>
<xsl:when test="$parameterName=substring-before($parameterString,
'=')">
<!-- required parameter is the first in the string, so extract and
return its value: -->
<xsl:choose>
<xsl:when test="contains($parameterString, '&')">
<xsl:value-of select="substring-before(substring-
after($parameterString, '='), '&')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-after($parameterString,
'=')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- if this is not the last name-value pair, call the routine
recursively, passing it the remainder of the string: -->
<xsl:if test="contains($parameterString, '&')">
<xsl:call-template name="getParameterValue">
<xsl:with-param name="parameterName" select="$parameterName"/>
<xsl:with-param name="parameterString" select="substring-
after($parameterString, '&')"/>
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
(Not tested!). Hope this helps,
Richard Light.
Richard Light
SGML/XML and Museum Information Consultancy
richard@light.demon.co.uk
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list