Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Can xslt have nested loops? 2

Status
Not open for further replies.

abs2003

MIS
Aug 31, 2004
80
US
Hello all,
I know this may be very simple but I don't know how? I have this XML file:
Code:
  <?xml version="1.0" ?> 
- <ASSORTMENT>
-   <FIXEDASSORTMENT>
     <DESCRIPTION>NACS SMALL ASSORTMENT</DESCRIPTION> 
      <COST>0.00</COST> 
      <ITEMNO>954469N</ITEMNO> 
-     <ITEMS>
       <ITEM>$4.99 JUV ASST</ITEM> 
       <ITEM>$6.99 FIC ASST</ITEM> 
       <ITEM>$6.99 NON FIC ASST</ITEM> 
       <ITEM>$9.99 HOUSE/HOME ASST</ITEM> 
      </ITEMS>
    </FIXEDASSORTMENT>
-   <FIXEDASSORTMENT>
     <DESCRIPTION>NACS MEDIUM ASSORTMENT</DESCRIPTION> 
     <COST>0.00</COST> 
     <ITEMNO>954470N</ITEMNO> 
-    <ITEMS>
      <ITEM>$4.99 JUV ASST</ITEM> 
      <ITEM>$6.99 FIC ASST</ITEM> 
      <ITEM>$6.99 NON FIC ASST</ITEM> 
      <ITEM>$9.99 HOUSE/HOME ASST</ITEM> 
     </ITEMS>
    </FIXEDASSORTMENT>
.
.

And this is my XSLT style sheet:
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform"[/URL] xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
	<xsl:template match="ASSORTMENT">
		<table width="90%" border="0" cellSpacing="0" cellPadding="0">	
			<xsl:for-each select="FIXEDASSORTMENT">
				<table width="70%" border="0" cellSpacing="0" cellPadding="0">
					<tr bgcolor="LIGHTBLUE">
						<td width="100"><font face="Arial,Helvetica,sans-serif" size="2" color="black"><b><xsl:value-of select="ITEMNO"/></b></font></td>
						<td><font face="Arial,Helvetica,sans-serif" size="2" color="black"><b><xsl:value-of select="DESCRIPTION"/></b></font></td>
						<td width="100" align="RIGHT"><font face="Arial,Helvetica,sans-serif" size="2" color="black"><b><xsl:value-of select="format-number(COST, '$#,##0.00')"/></b></font></td>
					</tr>
					<xsl:for-each select="/ASSORTMENT/FIXEDASSORTMENT/ITEMS">
						<tr bgcolor="LIGHTYELLOW">
							<td><font face="Arial,Helvetica,sans-serif" size="2" color="black">&#160;&#160;</font></td>
							<td colspan="2"><font face="Arial,Helvetica,sans-serif" size="2" color="black"><xsl:value-of select="ITEM"/></font></td>
						</tr>
					</xsl:for-each>
				</table>
			
				<br/>
			</xsl:for-each>
		</table>
	</xsl:template>
</xsl:stylesheet>

No matter what I do, I keep getting result like this:
[red]
954469N NACS SMALL ASSORTMENT $0.00
$4.99 JUV ASST
$4.99 JUV ASST
$4.99 JUV ASST
$4.99 JUV ASST

954469N NACS MEDUIMASSORTMENT $0.00
$4.99 JUV ASST
$4.99 JUV ASST
$4.99 JUV ASST
$4.99 JUV ASST
.
.
.
[/red]
Any idea what I did wrong?
 
Try changing
Code:
<xsl:for-each select="/ASSORTMENT/FIXEDASSORTMENT/ITEMS">
to
Code:
<xsl:for-each select="ITEMS">
You want the inner for-each to iterate over the ITEMS in the context of the node selected by the outer for-each.

Tom Morrison
 
Pressed Submit too quickly...

Then you need to change
Code:
<xsl:value-of select="ITEM"/>
to
Code:
<xsl:value-of select="."/>
to select the value of the current node within the context of the inner for-each.

I think you are missing the fact that xsl:for-each changes the context to refer to a specific node within the set of nodes over which you are iterating. This is sort of like the idea of 'current directory' in a file system reference. Your xsl:value-of was reselecting the same node value because the select="ITEM" was selecting the entire nodeset of ITEM nodes each time through the loop.

Tom Morrison
 
I fixed my problem by making my XML file as
Code:
 <?xml version="1.0" ?> 
- <ASSORTMENT>
- <FIXEDASSORTMENT>
  <DESCRIPTION>NACS SMALL ASSORTMENT</DESCRIPTION> 
  <COST>0.00</COST> 
  <ITEMNO>954469N</ITEMNO> 
- <ITEMS>[b][COLOR=red]
- <ITEM>
  <ITEM>$4.99 JUV ASST</ITEM> 
  </ITEM>
- <ITEM>
  <ITEM>$6.99 FIC ASST</ITEM> 
  </ITEM>
- <ITEM>
  <ITEM>$6.99 NON FIC ASST</ITEM> 
  </ITEM>
- <ITEM>
  <ITEM>$9.99 HOUSE/HOME ASST</ITEM> 
  </ITEM>[/color][/b]
  </ITEMS>
  <EXIST>TRUE</EXIST> 
  </FIXEDASSORTMENT>
- <FIXEDASSORTMENT>
  <DESCRIPTION>NACS MEDIUM ASSORTMENT</DESCRIPTION> 
  <COST>0.00</COST> 
  <ITEMNO>954470N</ITEMNO> 
- <ITEMS>[b][COLOR=red]
- <ITEM>
  <ITEM>$4.99 JUV ASST</ITEM> 
  </ITEM>
- <ITEM>
  <ITEM>$6.99 FIC ASST</ITEM> 
  </ITEM>
- <ITEM>
  <ITEM>$6.99 NON FIC ASST</ITEM> 
  </ITEM>
- <ITEM>
  <ITEM>$9.99 HOUSE/HOME ASST</ITEM> 
  </ITEM>[b][COLOR=red]
  </ITEMS>
  <EXIST>TRUE</EXIST> 
  </FIXEDASSORTMENT>
.
.
.

and my XSLT as...
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform"[/URL] xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
	<xsl:template match="/">
		<table width="90%" border="0" cellSpacing="0" cellPadding="0">[b][COLOR=red]	
			<xsl:for-each select="ASSORTMENT/FIXEDASSORTMENT">[/color][/b]
				<table width="70%" border="0" cellSpacing="0" cellPadding="0">
					<tr bgcolor="#99CC99">
						<td width="100"><font face="Arial,Helvetica,sans-serif" size="2"><b><xsl:value-of select="ITEMNO"/></b></font></td>
						<td><font face="Arial,Helvetica,sans-serif" size="2"><b><xsl:value-of select="DESCRIPTION"/></b></font></td>
						<td width="100" align="RIGHT"><font face="Arial,Helvetica,sans-serif" size="2" color="Red"><b><xsl:value-of select="format-number(COST, '$#,##0.00')"/></b></font></td>
					</tr>[b][COLOR=red]
					<xsl:for-each select="ITEMS/ITEM">[/color][/b]
						<tr bgcolor="LIGHTYELLOW">
							<td><font face="Arial,Helvetica,sans-serif" size="2" color="black">&#160;&#160;</font></td>
							<td colspan="2"><font face="Arial,Helvetica,sans-serif" size="2" color="black"><xsl:value-of select="ITEM"/></font></td>
						</tr>
					</xsl:for-each>
					<tr bgcolor="LIGHTYELLOW">
						<td colspan="3"><font face="Arial,Helvetica,sans-serif" size="1" color="black">&#160;&#160;</font></td>
					</tr>
				</table>
					<xsl:if test="string-length(EXIST)">
								
					<IMG src="images/btn_addItemsToCart.gif" border="0"/>
					</xsl:if>
				
				<br/><font face="Arial,Helvetica,sans-serif" size="1" color="black">&#160;&#160;</font>
				<br/>
			</xsl:for-each>
		</table>
	</xsl:template>
</xsl:stylesheet>

It's now working great. I know there is a better way to do this. But it works for me right now. I don't know why
Code:
<xsl:for-each select="ITEMS">
alone didn't work before.


Thank you all.
 
Yes there is a better way than bludgeoning your input (which is already too convoluted). Here is the entire stylesheet derived from your original post, modified as indicated, with my error corrected.
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform"[/URL] xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
    <xsl:template match="ASSORTMENT">
        <table width="90%" border="0" cellSpacing="0" cellPadding="0">    
            <xsl:for-each select="FIXEDASSORTMENT">
                <table width="70%" border="0" cellSpacing="0" cellPadding="0">
                    <tr bgcolor="LIGHTBLUE">
                        <td width="100"><font face="Arial,Helvetica,sans-serif" size="2" color="black"><b><xsl:value-of select="ITEMNO"/></b></font></td>
                        <td><font face="Arial,Helvetica,sans-serif" size="2" color="black"><b><xsl:value-of select="DESCRIPTION"/></b></font></td>
                        <td width="100" align="RIGHT"><font face="Arial,Helvetica,sans-serif" size="2" color="black"><b><xsl:value-of select="format-number(COST, '$#,##0.00')"/></b></font></td>
                    </tr>
                    [COLOR=red]<xsl:for-each select="ITEMS/ITEM">[/color]
                        <tr bgcolor="LIGHTYELLOW">
                            <td><font face="Arial,Helvetica,sans-serif" size="2" color="black">&#160;&#160;</font></td>
                            <td colspan="2"><font face="Arial,Helvetica,sans-serif" size="2" color="black"><xsl:value-of [COLOR=red]select="."/>[/color]</font></td>
                        </tr>
                    </xsl:for-each>
                </table>
            
                <br/>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

Regarding your lack of understanding, I will again call your attention to the mechanism of xsl:for-each. The select="ITEMS" says please iterate of all the nodes named ITEMS within my current context of FIXEDASSORTMENT. Since each FIXEDASSORTMENT had exactly one ITEMS node, that does not do what is wanted, which is to iterate over the nodeset of all ITEM subordinate to ITEMS within my current context of FIXEDASSORTMENT.

Tom Morrison
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top