Let's go through your steps because it's pretty clear what is going on and how to fix it.
You start with the following string: "Smith Antony Blah Jones"
Then you assign to the variable query
the result of substring-before
on the first string. That assigns "Smith"
to query
.
Then you assign query2
the value of a substring-before
of a substring-after
of your original string. The substring-after
returns "Antony Blah Jones"
, and the substring-before
returns "Antony"
. So far so good.
Now your next assignment looks for "Antony"
in the original string, but then your resulting string is " Blah Jones"
, so when you run substring-before
, you match the very first whitespace.
There are very many possible solutions to this. An obvious one would be calling substring-after
before calling substring-before
, like this:
<xsl:value-of
select="substring-before(substring-after(substring-after(root/@query, $query1), ' '),' ')"
/>
But that's pretty ugly. Alternatively you can use substring
or just tack on a space to "Antony"
when you do your first substring-after
call.
I think you're better off defining a recursive template to grab the next token then pass the remaining string to itself. This will let you grab an arbitrary number of space-separated tokens from a string without having to have so many numbered variables. Something like this:
<xsl:template name="recursive-tokenizer">
<xsl:param name="input"/>
<xsl:choose>
<!-- Test whether the input token contains a space. -->
<xsl:when test="contains($input,' ')">
<!-- Output a token. -->
<xsl:value-of select="substring-before($input,' ')"/>
<!-- Call this template with the rest of the string. -->
<xsl:call-template name="recursive-tokenizer">
<xsl:with-param name="input" select="substring-after($input,' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- There is no space, so just output the input. -->
<xsl:value-of select="$input"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>