title: XML to CSV with XSLT multiple node
body: <p>I am trying to convert xml file to CSV format using XSLT. 
  My XML file has multiple root (Account) with attributes and also with children of differend types.</p>
  
  <p><strong>Here is my XML:</strong></p>
  
  <pre><code>&lt;SiebelMessage&gt;
  &lt;ListOfSwiOrganizationIO&gt;
      &lt;Account&gt;
          &lt;Email&gt;jozk8o@sk.ibm.com&lt;/Email&gt;
          &lt;Name&gt;ESET&lt;/Name&gt;
          &lt;Address&gt;
              &lt;StreetAddress&gt;Vodna 9&lt;/StreetAddress&gt;
              &lt;City&gt;Nitra&lt;/City&gt;
          &lt;/Address&gt;
          &lt;Contact&gt;
              &lt;LastName&gt;Jozo&lt;/LastName&gt;
              &lt;FirstName&gt;Sekera&lt;/FirstName&gt;
          &lt;/Contact&gt;
          &lt;AccountCategory&gt;
              &lt;CategoryValue&gt;90&lt;/CategoryValue&gt;
          &lt;/AccountCategory&gt;
          &lt;AccountCategory&gt;
              &lt;CategoryValue&gt;91&lt;/CategoryValue&gt;
          &lt;/AccountCategory&gt;
          &lt;IntegrityCode&gt;
              &lt;IntegrityType&gt;AllowSms&lt;/IntegrityType&gt;
              &lt;ConsentCode&gt;YES&lt;/ConsentCode&gt;
          &lt;/IntegrityCode&gt;
          &lt;IntegrityCode&gt;
              &lt;IntegrityType&gt;AllowEmail&lt;/IntegrityType&gt;
              &lt;ConsentCode&gt;YES&lt;/ConsentCode&gt;
          &lt;/IntegrityCode&gt;
      &lt;/Account&gt;
      &lt;Account&gt;
          &lt;Email&gt;ferk8o@sk.ibm.com&lt;/Email&gt;
          &lt;Name&gt;IBM&lt;/Name&gt;
          &lt;Address&gt;
              &lt;StreetAddress&gt;Dlha 1&lt;/StreetAddress&gt;
              &lt;City&gt;Bratislava&lt;/City&gt;
          &lt;/Address&gt;
          &lt;Contact&gt;
              &lt;LastName&gt;Fero&lt;/LastName&gt;
              &lt;FirstName&gt;Kopacka&lt;/FirstName&gt;
          &lt;/Contact&gt;
          &lt;AccountCategory&gt;
              &lt;CategoryValue&gt;90&lt;/CategoryValue&gt;
          &lt;/AccountCategory&gt;
          &lt;AccountCategory&gt;
              &lt;CategoryValue&gt;91&lt;/CategoryValue&gt;
          &lt;/AccountCategory&gt;
          &lt;IntegrityCode&gt;
              &lt;IntegrityType&gt;AllowSms&lt;/IntegrityType&gt;
              &lt;ConsentCode&gt;YES&lt;/ConsentCode&gt;
          &lt;/IntegrityCode&gt;
          &lt;IntegrityCode&gt;
              &lt;IntegrityType&gt;AllowEmail&lt;/IntegrityType&gt;
              &lt;ConsentCode&gt;YES&lt;/ConsentCode&gt;
          &lt;/IntegrityCode&gt;
      &lt;/Account&gt;
  &lt;/ListOfSwiOrganizationIO&gt;
  </code></pre>
  
  <p></p>
  
  <p>I was able to create XSLT based on some articles here but only displaying the root attributes without children.</p>
  
  <p>Required output is:</p>
  
  <pre><code>Email;Name;StreetAddress;City;LastName;FirstName;CategoryValue;AllowSms;AllowEmail
  jozk8o@sk.ibm.com;ESET;Vodna 9;Nitra;Jozo;Sekera;90,91;YES;NOTSET
  ferk8o@sk.ibm.com;IBM;Dlha 1;Bratislava;Fero;Kopacka;90,91;YES;NO
  </code></pre>
  
  <p><strong>Here is my current XSLT:</strong></p>
  
  <pre><code>&lt;xsl:output method="text" encoding="utf-8"/&gt;
  &lt;xsl:strip-space elements="*"/&gt;
  &lt;xsl:variable name="delimiter" select="';'"/&gt;
  &lt;xsl:template match="/"&gt;
  &lt;!-- Output the CSV header --&gt;
  &lt;xsl:text&gt;Email;Name;StreetAddress;City;LastName;FirstName;CategoryValue;AllowSms;AllowEmail&amp;#10;&lt;/xsl:text&gt; 
  &lt;!-- Output the values --&gt;
  &lt;xsl:for-each select="SiebelMessage/ListOfSwiOrganizationIO/Account"&gt;
      &lt;!-- begin values --&gt;
      &lt;xsl:value-of select="concat(Email, $delimiter, Name, $delimiter, ListOfAddress/Address/StreetAddress, $delimiter, ListOfAddress/Address/City, $delimiter, Contact/LastName, $delimiter, Contact/FirstName, $delimiter)"/&gt;
      &lt;!-- Category Values --&gt;
      &lt;xsl:for-each select="AccountCategory"&gt;
          &lt;xsl:value-of select="CategoryValue"/&gt;
          &lt;xsl:if test="position()!=last()"&gt;
              &lt;xsl:text&gt;,&lt;/xsl:text&gt; 
          &lt;/xsl:if&gt;
      &lt;/xsl:for-each&gt;
      &lt;xsl:value-of select="$delimiter"/&gt;
      &lt;!-- Integrity Codes --&gt;
      &lt;xsl:value-of select="concat(IntegrityCode[IntegrityType='AllowSms']/ConsentCode, $delimiter, IntegrityCode[IntegrityType='AllowEmail']/ConsentCode)"/&gt;
      &lt;xsl:choose&gt;
            &lt;xsl:when test="ConsentCode=YES"&gt;
               (1)
            &lt;/xsl:when&gt;
         &lt;/xsl:choose&gt;
      &lt;!-- end values --&gt;
      &lt;xsl:if test="position()!=last()"&gt;
          &lt;xsl:text&gt;&amp;#10;&lt;/xsl:text&gt; 
      &lt;/xsl:if&gt;
  &lt;/xsl:for-each&gt;
  </code></pre>
  
  <p></p>
  
  <p>Could you please advice how to implement also children?
  My current output is only:</p>
  
  <pre><code>EMAIL;NAME
  jozk8o@sk.ibm.com;ESET;
  ferk8o@sk.ibm.com;IBM;
  </code></pre>
  
  <p>Thank you very much</p>