title: XSLT to find all nodes in one list that aren't in another
body: <p>I have xml that essentialy looks like the following (my actual .xml is a build log containing a union of VStudio and DotCover build output):</p>
  
  <pre><code>&lt;buildlog&gt;
    &lt;Projects&gt;
      &lt;project name="project1.csproj" /&gt;
      &lt;project name="project2.csproj" /&gt;
      &lt;project name="project3.csproj" /&gt;
      &lt;project name="project4.csproj" /&gt;
    &lt;/Projects&gt;
    &lt;Root&gt;
      &lt;Assembly Name="project1" /&gt;
      &lt;Assembly Name="project2" /&gt;
    &lt;/Root&gt;
  &lt;/buildlog&gt;
  </code></pre>
  
  <p>I need a list of all project nodes that don't have a corresponding @name match on @Name in the set of Root/Assembly nodes.  My goal here is to generate a report showing all projects that don't have code coverage.</p>
  
  <p>Here's the beginnings of my xsl stylesheet:</p>
  
  <pre><code>    &lt;xsl:template match="/"&gt;
          &lt;xsl:apply-templates select="buildlog/Projects" /&gt;
        &lt;/xsl:template&gt;
  
        &lt;xsl:template match="Projects"&gt;
  
          &lt;table&gt;
            &lt;tr&gt;
               &lt;td&gt;Assemblies Not Covered:&lt;/td&gt;
               &lt;td&gt;&lt;xsl:value-of select="count(./project)"/&gt;&lt;/td&gt;
            &lt;/tr&gt;
          &lt;/table&gt;
  
          &lt;xsl:apply-templates select="project" /&gt;
  
        &lt;/xsl:template&gt;
  
        &lt;xsl:template match="project"&gt;
  
          &lt;table&gt;
            &lt;tr&gt;
              &lt;td style="padding-left:30px"&gt;
                &lt;xsl:value-of select="substring-before(./@name,'.csproj')"/&gt;
              &lt;/td&gt;
            &lt;/tr&gt;
          &lt;/table&gt;
  
        &lt;/xsl:template&gt;
  </code></pre>
  
  <p>Thanks in advance.</p>
  
  <p><strong>INTERIM SOLUTION</strong></p>
  
  <p>For the time being I solved my issue using ms:script extensions. Below is the code.
  Not the most elegant give it is a Windows only solution, but it solved the problem. I'll
  the things other folks recommended and answer back in the comment sections.</p>
  
  <pre><code>Here's my solution:
  
  &lt;xsl:stylesheet version="1.0"
                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  xmlns="http://www.w3.org/TR/xhtml1/strict"
                  xmlns:ms="urn:schemas-microsoft-com:xslt"
                  xmlns:dsi="urn:dsi-scripts"&gt;
    &lt;xsl:output method="html"/&gt;
  
    &lt;xsl:template match="/"&gt;
  
      &lt;xsl:apply-templates select="buildlog/Projects" /&gt;
  
  
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="Projects"&gt;
      &lt;table&gt;
        &lt;tr&gt;
          &lt;td&gt;Assemblies Not Covered:&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/table&gt;
  
      &lt;xsl:apply-templates select="project" /&gt;
  
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="project"&gt;
      &lt;xsl:variable name="assemblies" select="//Assembly" /&gt;
  
      &lt;xsl:if test="not(dsi:HasCoverage($assemblies/@Name, ./@name))"&gt;
        &lt;table&gt;
          &lt;tr&gt;
            &lt;td style="padding-left:30px"&gt;
              &lt;xsl:value-of select="substring-before(./@name,'.csproj')"/&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/table&gt;
      &lt;/xsl:if&gt;
  
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="Assembly"&gt;
      &lt;table&gt;
        &lt;tr&gt;
          &lt;td style="padding-left:30px"&gt;
            &lt;xsl:value-of select="@Name"/&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
      &lt;/table&gt;
    &lt;/xsl:template&gt;
  
    &lt;ms:script language="C#" implements-prefix="dsi"&gt;
      &lt;![CDATA[
        public bool HasCoverage(XPathNodeIterator assemblies, string project)
        {
          bool result = false;
          while(assemblies.MoveNext())
          {
            if(assemblies.Current.Value == project.Replace(".csproj",string.Empty))
            {
              result = true;
              break;
            }
          }
          return result;
        }
  
      ]]&gt;
    &lt;/ms:script&gt;
  
  &lt;/xsl:stylesheet&gt;
  </code></pre>