title: How to filter in XSL?
body: <p>I'm learning XSLT and am practicing on trying to filter an existing XML file, and basically copy the tree with only selected nodes of interest - if they have match the condition say having the substring 'test'.</p>
  
  <p>Using the identity transform pattern, I have the following snippet:</p>
  
  <pre><code>&lt;xsl:template match="node() | @*"&gt;
      &lt;xsl:copy&gt;
          &lt;xsl:apply-templates select="(node() |  @*)[contains(name(.), 'test')]" /&gt;
  
  &lt;!-- Bonus Q: What would be happening behind the scenes when I put this code inside the copy element?
  &lt;xsl:value-of select="." /&gt; --&gt;
  
      &lt;/xsl:copy&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>Now this gets me the following output,</p>
  
  <pre><code>&lt;head&gt;
  &lt;testA&gt; &lt;testAChild /&gt;&lt;/testA&gt; &lt;!-- should be &lt;testA&gt; &lt;testAChild&gt; foo &lt;/testAChild&gt;&lt;/testA&gt; --&gt;
  &lt;testB /&gt; &lt;!-- should be &lt;testB&gt; bar &lt;/testB&gt; --&gt;
  &lt;Ctest /&gt; &lt;!-- should be &lt;Ctest&gt; foobar &lt;/Ctest&gt; --&gt;
            &lt;!-- should be &lt;DontDeleteThis&gt; &lt;testD&gt; 420 &lt;/testD&gt;&lt;/DontDeleteThis&gt; --&gt;
  &lt;/head&gt;
  </code></pre>
  
  <p>However, it doesn't have the values in the resulting tree. Furthermore, it isn't checking every case when the current node is false but the child, grandchildren, or possibly grand grand children could pass the criteria.</p>
  
  <p>Here is an example of the input XML:</p>
  
  <pre><code>&lt;head&gt;
      &lt;testA&gt;
          &lt;testAChild&gt; foo &lt;/testAChild&gt;
      &lt;/testA&gt;
      &lt;testB&gt; bar &lt;/testB&gt;
      &lt;Ctest&gt; foobar &lt;/Ctest&gt;
      &lt;DeleteThis&gt; DELETED &lt;/DeleteThis&gt;
      &lt;DontDeleteThis&gt;
          &lt;testD&gt;  420 &lt;/testD&gt;
      &lt;/DontDeleteThis&gt;
  &lt;/head&gt;
  </code></pre>