ank5
asked on
XSL - substring between 2 commas
In XSL, I am parsing some valus such as
I was trying to using substring-after and substring-before functions for this.
Let's say these values are an XML attribute called ver, so
would print the values listed above.
Now, If I do
it gets rid of 'a' and print 'b' and 'c' values (b, c). Then I wrapped this in a substring-before to get rid of 'c'
This works fine when the input being parsed is
it print's b as expected. However, when the input is
nothing displays.
How can handle both these scenarios and always print whatever is there at b position.
,b,c
a,b,c
There will always be 2 commas but text before the first comma may or may not be there. I need to display the text at position b (without the commas).I was trying to using substring-after and substring-before functions for this.
Let's say these values are an XML attribute called ver, so
<xsl:value-of select="ver"/>
would print the values listed above.
Now, If I do
<xsl:value-of select="substring-after(ver, ',')"/>
it gets rid of 'a' and print 'b' and 'c' values (b, c). Then I wrapped this in a substring-before to get rid of 'c'
<xsl:value-of select="substring-before(substring-after(ver, ','), ',')"/>
This works fine when the input being parsed is
a,b,c
it print's b as expected. However, when the input is
,b,c
nothing displays.
How can handle both these scenarios and always print whatever is there at b position.
Not done but this is start
<xsl:when test="starts-with(substring-before(substring-after(ver, ','), ',') , ',')">
<xsl:value-of select="substring-before(substring-after(ver, ','), ',')" />
<xsl:otherwise>
<xsl:value-of select="substring-before(substring-after(ver, ','), ',')" />
</xsl:otherwise>
</xsl:when>
Come to think of it, I agree with Geert
@shaun, please note that the xsl:otherwise should be outside the xsl:when, not in it
The test will however always fail because of this statement
The test will however always fail because of this statement
There will always be 2 commas
Yup, was still editing until I read your comment :) and decided to abandon until more info is given by OP
agreed,
the choose would be the way ahead if it would not be certain there are two commas
waiting for ank5 now ;-)
the choose would be the way ahead if it would not be certain there are two commas
waiting for ank5 now ;-)
ASKER
My apologies, there is a third scenario which I had overlooked and that is causing the problem
,b,c
a,b,c
,b
In all these 3 cases, I just want b to be printed. Sorry for the confusion.
,b,c
a,b,c
,b
In all these 3 cases, I just want b to be printed. Sorry for the confusion.
Hi,
you can get around with all sorts of testing
But I would make a named template that recursively scans the string for tokens based on a seperator
And use that to get the index 2
That would be a very generic solution
you can get around with all sorts of testing
But I would make a named template that recursively scans the string for tokens based on a seperator
And use that to get the index 2
That would be a very generic solution
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:variable name="ver1">a,b,c</xsl:variable>
<xsl:variable name="ver2">,b,c</xsl:variable>
<xsl:variable name="ver3">,b</xsl:variable>
<xsl:template match="/">
<vers>
<ver1>
<xsl:call-template name="get-token-by-index">
<xsl:with-param name="str" select="$ver1"></xsl:with-param>
<xsl:with-param name="index" select="2"/>
</xsl:call-template>
</ver1>
<ver2>
<xsl:call-template name="get-token-by-index">
<xsl:with-param name="str" select="$ver2"></xsl:with-param>
<xsl:with-param name="index" select="2"/>
</xsl:call-template>
</ver2>
<ver3>
<xsl:call-template name="get-token-by-index">
<xsl:with-param name="str" select="$ver3"></xsl:with-param>
<xsl:with-param name="index" select="2"/>
</xsl:call-template>
</ver3>
</vers>
</xsl:template>
<xsl:template name="get-token-by-index">
<xsl:param name="str"/>
<xsl:param name="sep" select="','"/>
<xsl:param name="index" select="1"/>
<xsl:choose>
<xsl:when test="contains($str, $sep) and $index > 1">
<xsl:call-template name="get-token-by-index">
<xsl:with-param name="str" select="substring-after($str, $sep)"/>
<xsl:with-param name="index" select="$index - 1"/>
<xsl:with-param name="sep" select="$sep"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($str, $sep)">
<xsl:value-of select="substring-before($str, $sep)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$str"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:template name="get-token-by-index">
is the template you need to copy to your code
and then use it as in the examples above it
is the template you need to copy to your code
and then use it as in the examples above it
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much for the solution, it works great.
My apologies for the delay in closing the question.
My apologies for the delay in closing the question.
If the input really is what you say it is, your code wil return "b" in both scenarios
try this with any input
Open in new window