Re: xslt strings: 'substring-between'?

Subject: Re: xslt strings: 'substring-between'?
From: Richard Light <richard@xxxxxxxxxxxxxxxxx>
Date: Wed, 2 Aug 2000 09:32:53 +0100
In message <39870F57.40C29FDA@xxxxxxx>, Steve Morrison
<smorrison@xxxxxxx> 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 '&' ('&amp;') as
markers. 

To get the effect of 'substring-between', you can nest substring
commands, e.g.:

  substring-before(substring-after($parameterString, '='), '&amp;')

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, '&amp;')">
      ... 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, '&amp;')">
          <xsl:value-of select="substring-before(substring-
after($parameterString, '='), '&amp;')"/>
        </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, '&amp;')">
        <xsl:call-template name="getParameterValue">
          <xsl:with-param name="parameterName" select="$parameterName"/>
          <xsl:with-param name="parameterString" select="substring-
after($parameterString, '&amp;')"/>
        </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@xxxxxxxxxxxxxxxxx


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread