title: XSLT foreach loop
body: <p>I have only been introduced to xslt and xml in the last few weeks, and I urgently need some help to write some code to achieve what I want to achieve.
  I have the following xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;abc1 formName="Form"&gt;
      &lt;Level1&gt;
          &lt;Element1&gt;ZZZ&lt;/Element1&gt;
          &lt;Element2&gt;
              &lt;SubElement1&gt;Apples&lt;/SubElement1&gt;
              &lt;SubElement2&gt;Oranges&lt;/SubElement2&gt;
              &lt;SubElement3&gt;Pears&lt;/SubElement3&gt;
              &lt;SubElement4&gt;Blueberries&lt;/SubElement4&gt;
              &lt;SubElement5&gt;Milkshakes&lt;/SubElement5&gt;
          &lt;/Element2&gt;
      &lt;/Level1&gt;
      &lt;Level1&gt;
          &lt;Element1&gt;XXX&lt;/Element1&gt;
          &lt;Element2&gt;
              &lt;SubElement1&gt;Apples&lt;/SubElement1&gt;
              &lt;SubElement2&gt;Oranges&lt;/SubElement2&gt;
              &lt;SubElement3&gt;Kiwifruit&lt;/SubElement3&gt;
              &lt;SubElement4&gt;Blueberries&lt;/SubElement4&gt;
              &lt;SubElement5&gt;Soda&lt;/SubElement5&gt;
          &lt;/Element2&gt;
      &lt;/Level1&gt;
  &lt;/abc1&gt;
  </code></pre>
  
  <p>and the following html table:</p>
  
  <pre><code>&lt;table&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt; Row 1&lt;/td&gt;
      &lt;td width="540" colspan="4"&gt; Cell_A&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt;Types&lt;/td&gt;
      &lt;td width="180" &gt;Type 1&lt;/td&gt;
      &lt;td width="180" &gt;Type 2&lt;/td&gt;
      &lt;td width="180" &gt;Type 3&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt;Row 2&lt;/td&gt;
      &lt;td width="180" &gt;Cell_B&lt;/td&gt;
      &lt;td width="180" &gt;Cell_C&lt;/td&gt;
      &lt;td width="180" &gt;Cell_D&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt; Row 3&lt;/td&gt;
      &lt;td width="180" &gt;Cell_E&lt;/td&gt;
      &lt;td width="180" &gt;Cell_F&lt;/td&gt;
      &lt;td width="180" &gt;Cell_G&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt;Row 4&lt;/td&gt;
      &lt;td width="180" &gt;Cell_H&lt;/td&gt;
      &lt;td width="180" &gt;Cell_I&lt;/td&gt;
      &lt;td width="180" &gt;Cell_J&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt; Row 5&lt;/td&gt;
      &lt;td width="540" colspan="4"&gt; Cell_K&lt;/td&gt;
  &lt;/tr&gt;
  &lt;/table&gt;
  </code></pre>
  
  <p>I am having trouble using xslt to extract the data from the xml into the table because the rules that I need to apply make it very complicated. Below are the rules that need to apply to the cells that I am having troubles with.</p>
  
  <p>(1) If the <code>&lt;Element1&gt;</code> value is the same throughout the xml, then:</p>
  
  <p>If <code>&lt;Element1&gt;</code> = 'ZZZ' then Cell_B = '10', Cell_C = '20', and Cell_D = '30'</p>
  
  <p>If <code>&lt;Element1&gt;</code> = 'XXX' then Cell_B = '100', Cell_C = '90', and Cell_D = '80'</p>
  
  <p>but if the <code>&lt;Element1&gt;</code> value differs in the xml, then:</p>
  
  <p>Cell_B = '10,100', Cell_C = '20,90', and Cell_D = '30,80'</p>
  
  <p>(2) If the <code>&lt;SubElement5&gt;</code> value is the same throughout the xml, then:</p>
  
  <p>Cell_J = the value of <code>&lt;SubElement5&gt;</code></p>
  
  <p>but if the <code>&lt;SubElement5&gt;</code> value differs in the xml, then:</p>
  
  <p>Cell_J = the value of both <code>&lt;SubElement5&gt;</code> values separated by a comma</p>
  
  <p>so in this case, the value for Cell_J would be  'Milkshakes, Soda'.</p>
  
  <p>I have been experimenting with different things using:</p>
  
  <pre><code>&lt;xsl:for-each select="./Level1/Element2"&gt;
  &lt;xsl:value-of select="./SubElement5"/&gt;
  &lt;/xsl:for-each&gt;
  </code></pre>
  
  <p>but I cant determine what code I can use to check if they are the same because I can't overwrite the value of a variable.</p>
  
  <p><strong>Edit:</strong> 
  Please note that the cells I've indicated above (cells b,c,d, and j) are the only ones I
  need help with. Additionally, for <code>Element1</code> there are four potential values I can 
  encounter: ZZZ, XXX, AAA, and BBB. The required values for each of these would be:
  (cells b,c, and d)</p>
  
  <pre><code>ZZZ:10,20,30
  XXX:100,90,80
  AAA:40,30,30
  BBB:50,30,20
  </code></pre>
  
  <p>so if there was only one potential value in the whole xml, the cells should appear with the values as above. If the two element 1 values are different, then the cells should list the above values in each cell, separated by a comma.</p>
  
  <p>With respect to cell_j, I'll try and explain it a little better.</p>
  
  <p>First, I need to determine if <code>&lt;SubElement5&gt;</code> is the same value throughout the xml. In this case it is not, in one section it is Milkshakes and in the other it is 'Soda'. Therefore, cell_J should contain the text 'Milkshakes, Soda'.</p>
  
  <p>If the xml looked like this:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
      &lt;abc1 formName="Form"&gt;
          &lt;Level1&gt;
              &lt;Element1&gt;ZZZ&lt;/Element1&gt;
              &lt;Element2&gt;
                  &lt;SubElement1&gt;Apples&lt;/SubElement1&gt;
                  &lt;SubElement2&gt;Oranges&lt;/SubElement2&gt;
                  &lt;SubElement3&gt;Pears&lt;/SubElement3&gt;
                  &lt;SubElement4&gt;Blueberries&lt;/SubElement4&gt;
                  &lt;SubElement5&gt;Milkshakes&lt;/SubElement5&gt;
              &lt;/Element2&gt;
          &lt;/Level1&gt;
          &lt;Level1&gt;
              &lt;Element1&gt;XXX&lt;/Element1&gt;
              &lt;Element2&gt;
                  &lt;SubElement1&gt;Apples&lt;/SubElement1&gt;
                  &lt;SubElement2&gt;Oranges&lt;/SubElement2&gt;
                  &lt;SubElement3&gt;Kiwifruit&lt;/SubElement3&gt;
                  &lt;SubElement4&gt;Blueberries&lt;/SubElement4&gt;
                  &lt;SubElement5&gt;Milkshakes&lt;/SubElement5&gt;
              &lt;/Element2&gt;
          &lt;/Level1&gt;
      &lt;/abc1&gt;
  </code></pre>
  
  <p>Then the value for cell_j would just be 'Milkshakes'.</p>
  
  <p>Thanks in advance to anyone who can help.</p>
  
  <p><strong>ANSWER TO THIS QUESTION:</strong></p>
  
  <p>To Summarize what Woody did below for anybody's future reference:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
  &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  
  &lt;xsl:template match="/abc1"&gt;
             &lt;xsl:variable name="elements" select="//Element1[not(preceding::Element1 = .)]"/&gt;
  &lt;table&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt; Row 1&lt;/td&gt;
      &lt;td width="540" colspan="4"&gt; Cell_A&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt;Types&lt;/td&gt;
      &lt;td width="180" &gt;Type 1&lt;/td&gt;
      &lt;td width="180" &gt;Type 2&lt;/td&gt;
      &lt;td width="180" &gt;Type 3&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt;Row 2&lt;/td&gt;
      &lt;td width="180" &gt; &lt;xsl:for-each select="$elements"&gt;
              &lt;xsl:if test="position() != 1"&gt;,&lt;/xsl:if&gt;
              &lt;xsl:choose&gt;
                  &lt;xsl:when test=". = 'AAA'"&gt;40&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'BBB'"&gt;50&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'XXX'"&gt;100&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'ZZZ'"&gt;10&lt;/xsl:when&gt;
              &lt;/xsl:choose&gt;
          &lt;/xsl:for-each&gt;&lt;/td&gt;
      &lt;td width="180" &gt;&lt;xsl:for-each select="$elements"&gt;
              &lt;xsl:if test="position() != 1"&gt;,&lt;/xsl:if&gt;
              &lt;xsl:choose&gt;
                  &lt;xsl:when test=". = 'AAA'"&gt;30&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'BBB'"&gt;30&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'XXX'"&gt;90&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'ZZZ'"&gt;20&lt;/xsl:when&gt;
              &lt;/xsl:choose&gt;
          &lt;/xsl:for-each&gt;&lt;/td&gt;
      &lt;td width="180" &gt;&lt;xsl:for-each select="$elements"&gt;
              &lt;xsl:if test="position() != 1"&gt;,&lt;/xsl:if&gt;
              &lt;xsl:choose&gt;
                  &lt;xsl:when test=". = 'AAA'"&gt;30&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'BBB'"&gt;20&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'XXX'"&gt;80&lt;/xsl:when&gt;
                  &lt;xsl:when test=". = 'ZZZ'"&gt;30&lt;/xsl:when&gt;
              &lt;/xsl:choose&gt;
          &lt;/xsl:for-each&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt; Row 3&lt;/td&gt;
      &lt;td width="180" &gt;Cell_E&lt;/td&gt;
      &lt;td width="180" &gt;Cell_F&lt;/td&gt;
      &lt;td width="180" &gt;Cell_G&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt;Row 4&lt;/td&gt;
      &lt;td width="180" &gt;Cell_H&lt;/td&gt;
      &lt;td width="180" &gt;Cell_I&lt;/td&gt;
      &lt;td width="180" &gt;&lt;xsl:for-each select="//SubElement5[not(preceding::SubElement5/text() = text())]"&gt;
         &lt;xsl:if test="position() &amp;gt; 1"&gt;, &lt;/xsl:if&gt;
         &lt;xsl:value-of select="."/&gt;
      &lt;/xsl:for-each&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
      &lt;td width="180" &gt; Row 5&lt;/td&gt;
      &lt;td width="540" colspan="4"&gt; Cell_K&lt;/td&gt;
  &lt;/tr&gt;
  &lt;/table&gt;
          &lt;/xsl:template&gt;
      &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>Woody, thank-you again. This was awesome.</p>