#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2005
    Posts
    44
    Rep Power
    9

    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) &gt; 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) &gt; 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.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2005
    Posts
    44
    Rep Power
    9
    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) &gt; 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!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2005
    Posts
    44
    Rep Power
    9
    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.

IMN logo majestic logo threadwatch logo seochat tools logo