0

I'm pretty new to XSL(T). I'm not sure its relevant but I'm working with IBM DataPower.

I'm trying to use XSL to parse an incoming URI which looks like this:

http://ip:port/Nucleus_v2.9.3/SomeEndPoint

I wish to extract the version (2.9.3) into one variable and the destination (SomeEndPoint) into a second variable. I'm attempting to use a recursive template that takes two parameters (the above URI and the slash character). Within the template I would like to use an element that will trace thru the URI and capture both values into variables.

<xsl:template name="parseIncomingURI">
    <xsl:param name="string" />
    <xsl:param name="char" />
    <xsl:choose>
        <xsl:when test="contains($string, $char) and contains($string, 'Nucleus_v')">
            <xsl:call-template name="parseIncomingURL">
                <xsl:with-param name="string" select="substring-after($string, $char)" />
                <xsl:with-param name="char" select="$char" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

I'm not sure what I'm attempting is possible and I may be misunderstanding what a template is meant to deliver. I want to assign the version in the "when" element above and then assign the end point variable in the "otherwise" (which would trigger after the last slash is encountered in the recursion).

For what it is worth, I simply call this template elsewhere in the XSL and pass the original URI and a '/' character as the two initial parameters. I realize in the "when" element I would need to acquire the version thru some substring-before and substring-after functions. I don't have that code included here as I think it clutters the example.

Am I on the right track? Any help or pointers would be greatly appreciated. I'll be glad to edit and add more info as needed.

Thanks, Chris

C. Suttle
  • 170
  • 1
  • 11
  • "*Within the template I would like to use an element that will trace thru the URI and capture both values into variables.*" That wouldn't have worked anyway: a variable defined within the template would be limited in scope to that template. – michael.hor257k Feb 23 '17 at 18:41
  • Good to know, I was wondering about that too. I will look at your answer below later today. Looks like you are dropping the recursion altogether which very well may be the way to go. I started down the recursion path thinking there could be more than just the two variables pulled from the URI path. So i wanted to do a split on '/' but found that wasn't directly possible and recursion might be a possible work-around. Way more info than you wanted lol...but thats what led me to recursion in the first place. – C. Suttle Feb 23 '17 at 19:11
  • Recursion would have made sense if you had multiple prefix/suffix pairs, and needed to extract the n-th token. Here's an example showing how to get the token before last - albeit with a uniform delimiter: http://stackoverflow.com/questions/38848374/how-to-find-last-to-preview-work-and-store-to-my-field-in-xslt/38848925#38848925 – michael.hor257k Feb 23 '17 at 21:24

2 Answers2

1

I don't think you need a recursive template here. You could extract the version as:

<xsl:variable name="version" select="substring-before(substring-after(URI, 'Nucleus_v'), '/')" />       

and the destination as:

<xsl:variable name="destination" select="substring-after(substring-after(URI, 'Nucleus_v'), '/')" />    

This is a purely XSLT 1.0 solution; if you're using IBM DataPower, you also have access to the EXSLT Regular Expression extension functions (according to their documentation).

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • Thanks michael.hor257k. I'm gonna use this. And I really appreciate the link to the EXSLT Regex extension functions. I'm starting a hopefully long journey with IBM DataPower and I'm sure this will come in handy. -Chris – C. Suttle Feb 23 '17 at 21:17
  • According to their documentation, they support a wide range of the EXSLT functions - some of these can be very handy. – michael.hor257k Feb 23 '17 at 21:26
1

Generally if you want to get two items of data from a computation, there are two ways of doing it:

(a) compute each one independently using separate functions / expressions / named templates

(b) write a function / expression / named template that returns a composite value. In XSLT 1.0 the only kind of composite value available is a nodeset. You then hit the result-tree-fragment restriction that you can't return nodesets, only RTFs - but that's easily circumvented using exslt:node-set().

(I've been known to manipulate composite values as structured strings, e.g. AAAA#BBBB, but that's getting a bit desperate.)

In this case I would go for (a) - two separate computations.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Thanks Michael, agreed, (a) is the way I plan to go. I was actually just looking at michael.hor257k's answer as the two function-based computations I think I'm gonna go with. Recursion template was just not needed here. I really appreciate your answer, I'll upvote if I'm able. Many thanks. – C. Suttle Feb 23 '17 at 21:15