title: xslt - How to filter a XML document using xslt, keep given elements, discard all others
body: <p>I have this xml:</p>
  
  <pre>
  <code>
  
      &lt;?xml version="1.0" encoding="utf-8"?&gt;
      &lt;xml&gt;
      &lt;head&gt;
          &lt;name&gt;This is my XML&lt;/name&gt;
          &lt;version&gt;This is my XML&lt;/version&gt;   
      &lt;/head&gt;
      &lt;body&gt;
          &lt;item id="SH2-99435"&gt;
              &lt;properties&gt;
                  &lt;property id="69"&gt;
                      &lt;name&gt;This is a property&lt;/name&gt;
                      &lt;amount&gt;54.13&lt;/amount&gt;
                      &lt;estructure id="IZ4"&gt;
                          &lt;name&gt;caterpillar&lt;/name&gt;
                          &lt;location&gt;&lt;zipCode&gt;02210&lt;/zipCode&gt;&lt;street&gt;South Station&lt;/street&gt;&lt;/location&gt;
                      &lt;/estructure&gt;
                  &lt;/property&gt;
                  &lt;features id="ABC3"&gt;
                      &lt;feature&gt;If it works, a bug is another feature.&lt;/feature&gt;
                      &lt;feature&gt;feature!!&lt;/feature&gt;
                  &lt;/features&gt;
              &lt;/properties&gt;
              &lt;coding&gt;
                  &lt;codename&gt;Silent Hill 2&lt;/codename&gt;
                  &lt;developer&gt;Team Silent&lt;/developer&gt;
                  &lt;publisher&gt;Konami&lt;/publisher&gt;
              &lt;/coding&gt;
          &lt;/item&gt;
          &lt;item id="SH3-4498"&gt;
              &lt;text value="it has values like the other item"/&gt;
          &lt;/item&gt;       
          &lt;item id="MGS-2"&gt;
              &lt;text value="it has values like the other item"/&gt;
          &lt;/item&gt;
      &lt;/body&gt;
      &lt;/xml&gt;
  
  </code>
  </pre>
  
  <p>And I want to achieve this:</p>
  
  <pre>
  <code>
  
      &lt;?xml version="1.0" encoding="utf-8"?&gt;
      &lt;xml&gt;
      &lt;head&gt;
          &lt;name&gt;This is my XML&lt;/name&gt;
          &lt;version&gt;This is my XML&lt;/version&gt;   
      &lt;/head&gt;
      &lt;body&gt;
          &lt;item&gt;
              &lt;properties&gt;
                  &lt;property id="69"&gt;
                      &lt;amount&gt;54.13&lt;/amount&gt;
                      &lt;estructure id="IZ4"&gt;
                          &lt;name&gt;caterpillar&lt;/name&gt;
                          &lt;location&gt;&lt;zipCode&gt;02210&lt;/zipCode&gt;&lt;street&gt;South Station&lt;/street&gt;&lt;/location&gt;
                      &lt;/estructure&gt;
                  &lt;/property&gt;
              &lt;/properties&gt;
          &lt;/item&gt;
          &lt;item id="SH3-4498"&gt;
              &lt;text value="it should have properties and the selected sons"/&gt;
          &lt;/item&gt;       
          &lt;item id="MGS-2" &gt;
              &lt;text value="it should have properties and the selected sons"/&gt;
          &lt;/item&gt;
      &lt;/body&gt;   
      &lt;/xml&gt;
      </code>
      </pre>
  
  <p>I have something like this, which filters correctly:</p>
  
  <pre>
  <code>
  
      &lt;?xml version="1.0" encoding="utf-8"?&gt;
      &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" &gt;
  
          &lt;xsl:template match="@*|node()"&gt;
              &lt;xsl:copy&gt;
                  &lt;xsl:apply-templates select="@*|node()"/&gt;
              &lt;/xsl:copy&gt;
          &lt;/xsl:template&gt;
  
          &lt;xsl:template match="xml/body/item/coding" /&gt;
          &lt;xsl:template match="xml/body/item/properties/features" /&gt;
          &lt;xsl:template match="xml/body/item/properties/property/name" /&gt;
  
      &lt;/xsl:stylesheet&gt;
  
  </code>
  </pre>
  
  <p>I have been told that there are going to be 10 files being produced by running this filter, each one with different tags; but if a new tag comes, we would have to change 10 files to exclude the unwanted tag, instead of only add a tag on the file that is needed. For example, on the other file, only coding is going to be included, and so on.</p>
  
  <p>I tried with this:</p>
  
  <pre>
  <code>    
  
      &lt;xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="some:ns"&gt;
          &lt;xsl:output omit-xml-declaration="yes" indent="yes" /&gt;
          &lt;xsl:strip-space elements="*" /&gt;
          &lt;ns:WhiteList&gt;
              &lt;name&gt;amount&lt;/name&gt;
              &lt;name&gt;estructure&lt;/name&gt;
          &lt;/ns:WhiteList&gt;
          &lt;xsl:template match="node()|@*"&gt;
              &lt;xsl:copy&gt;
                  &lt;xsl:apply-templates select="node()|@*" /&gt;
              &lt;/xsl:copy&gt;
          &lt;/xsl:template&gt;
          &lt;xsl:template
              match="*[not(descendant-or-self::*[name()=document('')/*/ns:WhiteList/*])]" /&gt;
      &lt;/xsl:stylesheet&gt;
      </code>
  
  </pre>
  
  <p>But it doesn't copy the children of estructure.
  Do you know what I could do?</p>
  
  <p>Thanks.</p>
  
  <p><strong>Update.</strong> Added justification to make it this way and not the other way around, and more descriptive question.</p>