January 3rd, 2011, 05:01 PM
-
Looping Through Pipe Separated Lists
I have two strings that are pipe separated such as:
ProductID=8901|8902|8903|8904|8905|8906|8907|8908|9089
ProductDisplayName=Song1|Song2|Song3|Song4|Song5|Song6|Song7|Song8|Song9
I am using ant to transform and format it so it looks like:
Code:
<Product>
<subscription/>
<ID>8901</ID>
<title>Song1</title>
</Product>
<Product>
<subscription/>
<ID>8902</ID>
<title>Song2</title>
</Product>
etc, you get the picture.
So far I have tried something creating 2 templates that will iterate through each list when called:
PHP Code:
TEMPLATES:
<xsl:template name="parseId">
<xsl:param name="toParse" select="normalize-space($ProductID)" />
<xsl:if test="string-length($toParse) > 0">
<ID>
<xsl:choose>
<xsl:when test="contains($toParse, '|')">
<xsl:value-of select="normalize-space(substring-before($toParse, '|'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space($toParse)" />
</xsl:otherwise>
</xsl:choose>
</ID>
<!-- Recurse -->
<xsl:call-template name="parseId">
<xsl:with-param name="toParse" select="substring-after(normalize-space($toParse), '|')" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="parseDisplayName">
<xsl:param name="toParse" select="normalize-space($ProductDisplayName)" />
<xsl:if test="string-length($toParse) > 0">
<title>
<xsl:choose>
<xsl:when test="contains($toParse, '|')">
<xsl:value-of select="normalize-space(substring-before($toParse, '|'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space($toParse)" />
</xsl:otherwise>
</xsl:choose>
</title>
<!-- Recurse -->
<xsl:call-template name="parseDisplayName">
<xsl:with-param name="toParse" select="substring-after(normalize-space($toParse), '|')" />
</xsl:call-template>
</xsl:if>
</xsl:template>
HOW THEY ARE CALLED:
<Product>
<xsl:choose>
<xsl:when test="nscl:capitalize($ProductType) = 'Free'">
<freeAccess />
</xsl:when>
<xsl:otherwise>
<subscription />
<xsl:call-template name="parseId">
<xsl:with-param name="toParse" select="$ProductID" />
</xsl:call-template>
<xsl:call-template name="parseDisplayName">
<xsl:with-param name="toParse" select="$ProductDisplayName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</Product>
And I end up with this which i feel is on the right track, but clearly not quite there yet:
PHP Code:
<Product>
<Product>
<subscription/>
<ID>8901</ID>
<ID>8902</ID>
<ID>8903</ID>
<ID>8904</ID>
<ID>8905</ID>
<ID>8906</ID>
<ID>8907</ID>
<ID>8908</ID>
<ID>9089</ID>
<title>Epix</title>
<title>Epix2</title>
<title>Eppi3</title>
<title>Epix4</title>
<title>Epxi5</title>
<title>Epix6</title>
<title>Epix7</title>
<title>Epix8</title>
<title>Epix9</title>
</Product>
I know why I only have one <Product></Product>, but I can figure out how I can loop through each inside one loop. Im really stumped. Any thoughts on how I can make this work?
If anything i wrote was unclear please ask. I don't mind clarifying.
Thanks in advance.
January 4th, 2011, 11:12 AM
-
Ok, I have been working on the logic and maybe I am getting closer? Now I just have an issue with getting a StackOverflow trying to recursively go through the list.
New template code:
Code:
<xsl:template name="parseSubscription">
<xsl:param name="parseId" select="normalize-space($ProductID)" />
<xsl:param name="parseDisplayName" select="normalize-space($ProductDisplayName)" />
<xsl:choose>
<xsl:when test="nscl:capitalize($ProductType) = 'Free'">
<Product>
<freeAccess />
</Product>
</xsl:when>
<xsl:otherwise>
<xsl:if test="string-length($parseId) > 0">
<Product>
<subscription/>
<ID>
<xsl:choose>
<xsl:when test="contains($parseId, '|')">
<xsl:value-of select="normalize-space(substring-before($parseId, '|'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space($parseId)" />
</xsl:otherwise>
</xsl:choose>
</ID>
<title>
<xsl:choose>
<xsl:when test="contains($parseDisplayName, '|')">
<xsl:value-of select="normalize-space(substring-before($parseDisplayName, '|'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space($parseDisplayName)" />
</xsl:otherwise>
</xsl:choose>
</title>
</Product>
<!-- Recurse -->
<xsl:call-template name="parseSubscription">
<xsl:with-param name="parseId" select="substring-after(normalize-space($ProductID), '|')" />
<xsl:with-param name="parseDisplayName" select="substring-after(normalize-space($ProductDisplayName), '|')" />
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
And how the template is called:
Code:
<xsl:call-template name="parseSubscription">
<xsl:with-param name="parseId" select="$ProductID" />
<xsl:with-param name="parseDisplayName" select="$ProductDisplayName" />
</xsl:call-template>
There must be something wrong with the way I am recursively calling the template, but I am not seeing it. If i remove the recursive call ant runs fine and outputs a proper xml but the only problem is of course I only get the first pair of ID and DisplayName.
Any ideas? Thanks!
January 4th, 2011, 11:55 AM
-
SOLVED!
I finally found the problem and it was extremely minor, thats how it usually is, right?
It was in my recursive call, OF COURSE.
Change the recursive call from:
Code:
<!-- Recurse -->
<xsl:call-template name="parseSubscription">
<xsl:with-param name="parseId" select="substring-after(normalize-space($ProductID), '|')" />
<xsl:with-param name="parseDisplayName" select="substring-after(normalize-space($ProductDisplayName), '|')" />
</xsl:call-template>
to this:
Code:
<!-- Recurse -->
<xsl:call-template name="parseSubscription">
<xsl:with-param name="parseId" select="substring-after(normalize-space($parseId), '|')" />
<xsl:with-param name="parseDisplayName" select="substring-after(normalize-space($parseDisplayName), '|')" />
</xsl:call-template>
Which makes sense to me in that if I kept passing the value of original variables ($ProductId, $ProductDisplayName) then it would never get to the end of the list. Instead I had to call the template recursively with the already parsed values in $parseId and $parseDisplayName so that it could actually move through the list.