<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
<!-- multilevel grouping using the Muench method -->

<!-- Establish a key for each grouping level.  Note that each lower level key value -->
<!-- must include the key value of the higher order key -->
  <xsl:key name="kFamily" match="item" use="Family"/>
  <xsl:key name="kVernacularNameOfFamily" match="item" use="VernacularNameOfFamily"/>
  <xsl:key name="kSubfamily" match="item" use="concat(Family,':',Subfamily)"/>
  <xsl:key name="kGenus" match="item" use="concat(Family,':',Subfamily,':',Genus)"/>

  <xsl:template match="/">
    <html>
<head>
  <title>Chrysidoidea</title>
  <link rel="stylesheet" type="text/css" href="chrysidoidea.css" title="default" />
</head>
      <body>
        <h1 class="superfamily">
          <xsl:value-of select="local-name(/*[1])"/>
        </h1>
        <!-- the outer for-each iterates once for each unique value of Family -->
        <xsl:for-each select="/*/item[generate-id() = generate-id(key('kFamily', Family)[1])]">
          <h2>
            <span class="Family"><xsl:value-of select="Family" /></span>
            <span class="VernacularNameOfFamily"><xsl:value-of select="VernacularNameOfFamily" /></span>
          </h2>

          <!-- this for-each iterates over the <item> nodes, once for each unique value of Subfamily -->
          <!-- that have the same value of Family as the containing for-each iteration -->
          <xsl:for-each select="key('kFamily', Family)
                                [generate-id()=
                                  generate-id(key('kSubfamily',concat(Family,':',Subfamily))[1])]">
            <xsl:if test="string-length(Subfamily) &gt; 0">
              <h3 class="Subfamily">
                <xsl:value-of select="Subfamily"/>
              </h3>
            </xsl:if>
            <!-- this for-each iterates over the <item> nodes, once for each unique value of Genus -->
            <!-- that have the same value of Family and Subfamily as the containing for-each iteration -->
            <xsl:for-each select="key('kSubfamily', concat(Family,':',Subfamily))
                                  [generate-id()=
                                    generate-id(key('kGenus',concat(Family,':',Subfamily,':',Genus))[1])]">
              <xsl:if test="string-length(Genus) &gt; 0">
                <h4>
                  <span class="Genus"><xsl:value-of select="Genus"/></span>
                  <span class="AuthorYearOfGenus"><xsl:value-of select="AuthorYearOfGenus"/></span>
                  <span class="VernacularNameOfGenus"><xsl:value-of select="VernacularNameOfGenus" /></span>
                 </h4>
              </xsl:if>
<xsl:if test="count(*[(substring-before(local-name(),'_') = 'SynonymOfGenus') and (string-length() &gt; 0)]) &gt; 0">
  <ul class="SynGen">
  <xsl:for-each select="*[(substring-before(local-name(),'_') = 'SynonymOfGenus') and (string-length() &gt; 0)]">
    <xsl:variable name="localNameModifier" select="substring-after(local-name(.),'SynonymOfGenus')"/>
    <xsl:variable name="authorElementName" select="concat('AuthorYearOfSynonymOfGenus',$localNameModifier)"/>
    <li class="nodot">
      <span class="{local-name(.)}"><xsl:value-of select="." /></span>
      <span>
        <xsl:attribute name="class"><xsl:value-of select="$authorElementName"/></xsl:attribute>
        <xsl:value-of select="../*[local-name() = $authorElementName]" />
      </span>
    </li>
  </xsl:for-each>
  </ul>
</xsl:if>
 
              <ul class="SciName">
                <!-- this for-each iterates once for each <item> node -->
                <!-- that has the same value of Family, Subfamily, and Genus as the -->
                <!-- containing for-each iteration -->
                <xsl:for-each select="key('kGenus',concat(Family,':',Subfamily,':',Genus))">
                  <!-- this for-each iterates over all the <ScientificName> nodes in the <item> -->
              <li>
                  <xsl:for-each select="ScientificName[string-length(text()) &gt; 0]">
                      <span class="ScientificName"><xsl:value-of select="."/></span>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfScientificName[string-length(text()) &gt; 0]">
                      <span class="AuthorYearOfScientificName"><xsl:value-of select="."/></span>
                  </xsl:for-each>

<xsl:if test="string-length(InfraspecificRank_1 or SynonymOfScientificName_1 or QestionableSynonym) &gt; 0">
  <ul class="SynSciName">


                  <xsl:for-each select="QestionableSynonym[string-length(text()) &gt; 0]">
                     <li class="inline">
                      <span class="QestionableSynonym"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfQestionableSynonym[string-length(text()) &gt; 0]">
                     <li class="inline">
                      <span class="AuthorYearOfQestionableSynonym"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="SynonymOfScientificName_1[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfScientificName_1"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfScientificName_1[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfScientificName_1"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="SynonymOfScientificName_2[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfScientificName_2"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfScientificName_2[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfScientificName_2"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="SynonymOfScientificName_3[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfScientificName_3"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfScientificName_3[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfScientificName_3"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="SynonymOfScientificName_4[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfScientificName_4"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfScientificName_4[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfScientificName_4"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="InfraspecificRank_1[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificRank_1"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="InfraspecificEpithet_1[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificEpithet_1"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfInfraspecificEpithet_1[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfInfraspecificEpithet_1"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>
 
                  <xsl:for-each select="SynonymOfInfraspecificEpithet_1[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfInfraspecificEpithet_1"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfInfraspecificEpithet_1[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfInfraspecificEpithet_1"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="InfraspecificRank_2[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificRank_2"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="InfraspecificEpithet_2[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificEpithet_2"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfInfraspecificEpithet_2[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfInfraspecificEpithet_2"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>
 
                  <xsl:for-each select="SynonymOfInfraspecificEpithet_2[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfInfraspecificEpithet_2"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfInfraspecificEpithet_2[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfInfraspecificEpithet_2"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="InfraspecificRank_3[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificRank_3"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="InfraspecificEpithet_3[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificEpithet_3"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfInfraspecificEpithet_3[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfInfraspecificEpithet_3"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>
 
                  <xsl:for-each select="SynonymOfInfraspecificEpithet_3[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfInfraspecificEpithet_3"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfInfraspecificEpithet_3[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfInfraspecificEpithet_3"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="InfraspecificRank_4[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificRank_4"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="InfraspecificEpithet_4[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificEpithet_4"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfInfraspecificEpithet_4[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfInfraspecificEpithet_4"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>
 
                  <xsl:for-each select="SynonymOfInfraspecificEpithet_4[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfInfraspecificEpithet_4"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfInfraspecificEpithet_4[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfInfraspecificEpithet_4"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

                  <xsl:for-each select="InfraspecificRank_5[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificRank_5"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="InfraspecificEpithet_5[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="InfraspecificEpithet_5"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfInfraspecificEpithet_5[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfInfraspecificEpithet_5"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>
 
                  <xsl:for-each select="SynonymOfInfraspecificEpithet_5[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="SynonymOfInfraspecificEpithet_5"><xsl:value-of select="."/></span>
                      </li>
                  </xsl:for-each>
                  <xsl:for-each select="AuthorYearOfSynonymOfInfraspecificEpithet_5[string-length(text()) &gt; 0]">
                      <li class="inline">
                      <span class="AuthorYearOfSynonymOfInfraspecificEpithet_5"><xsl:value-of select="."/></span>
                      </li>
                      <br />
                  </xsl:for-each>

  </ul>
</xsl:if>

              </li>
               </xsl:for-each>
             </ul>
            </xsl:for-each>       
          </xsl:for-each>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>