title: Remove all nodes from XML but specific ones in PHP
body: <p>I have an XML from Google with a content like this:</p>
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
  &lt;rss version=&quot;2.0&quot; xmlns:g=&quot;http://base.google.com/ns/1.0&quot;&gt;
   &lt;channel&gt;
    &lt;title&gt;E-commerce's products.&lt;/title&gt;
    &lt;description&gt;&lt;![CDATA[Clothing and accessories.]]&gt;&lt;/description&gt;
    &lt;link&gt;https://www.ourwebsite.com/&lt;/link&gt;
    &lt;item&gt;
     &lt;title&gt;&lt;![CDATA[Product #1 title]]&gt;&lt;/title&gt;
     &lt;g:brand&gt;&lt;![CDATA[Product #1 brand]]&gt;&lt;/g:brand&gt;
     &lt;g:mpn&gt;&lt;![CDATA[5643785645]]&gt;&lt;/g:mpn&gt;
     &lt;g:gender&gt;Male&lt;/g:gender&gt;
     &lt;g:age_group&gt;Adult&lt;/g:age_group&gt;
     &lt;g:size&gt;Unica&lt;/g:size&gt;
     &lt;g:condition&gt;new&lt;/g:condition&gt;
     &lt;g:id&gt;fr_30763_06352&lt;/g:id&gt;
     &lt;g:item_group_id&gt;fr_30763&lt;/g:item_group_id&gt;
     &lt;link&gt;&lt;![CDATA[https://www.ourwebsite.com/product_1_url.htm?mid=62367]]&gt;&lt;/link&gt;
     &lt;description&gt;&lt;![CDATA[Product #1 description]]&gt;&lt;/description&gt;
     &lt;g:image_link&gt;&lt;![CDATA[https://data.ourwebsite.com/imgprodotto/product-1_big.jpg]]&gt;&lt;/g:image_link&gt;
     &lt;g:sale_price&gt;29.25 EUR&lt;/g:sale_price&gt;
     &lt;g:price&gt;65.00 EUR&lt;/g:price&gt;
     &lt;g:shipping_weight&gt;0.5 kg&lt;/g:shipping_weight&gt;
     &lt;g:featured_product&gt;y&lt;/g:featured_product&gt;
     &lt;g:product_type&gt;&lt;![CDATA[Product #1 category]]&gt;&lt;/g:product_type&gt;
     &lt;g:availability&gt;in stock&lt;/g:availability&gt;
     &lt;g:availability_date&gt;2022-08-10T00:00-0000&lt;/g:availability_date&gt;
     &lt;qty&gt;3&lt;/qty&gt;
     &lt;g:payment_accepted&gt;Visa&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;MasterCard&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;CartaSi&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;Aura&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;PayPal&lt;/g:payment_accepted&gt;
    &lt;/item&gt;
    &lt;item&gt;
     &lt;title&gt;&lt;![CDATA[Product #2 title]]&gt;&lt;/title&gt;
     &lt;g:brand&gt;&lt;![CDATA[Product #2 brand]]&gt;&lt;/g:brand&gt;
     &lt;g:mpn&gt;&lt;![CDATA[573489547859]]&gt;&lt;/g:mpn&gt;
     &lt;g:gender&gt;Unisex&lt;/g:gender&gt;
     &lt;g:age_group&gt;Adult&lt;/g:age_group&gt;
     &lt;g:size&gt;Unica&lt;/g:size&gt;
     &lt;g:condition&gt;new&lt;/g:condition&gt;
     &lt;g:id&gt;fr_47362_382936&lt;/g:id&gt;
     &lt;g:item_group_id&gt;fr_47362&lt;/g:item_group_id&gt;
     &lt;link&gt;&lt;![CDATA[https://www.ourwebsite.com/product_2_url.htm?mid=168192]]&gt;&lt;/link&gt;
     &lt;description&gt;&lt;![CDATA[Product #2 description]]&gt;&lt;/description&gt;
     &lt;g:image_link&gt;&lt;![CDATA[https://data.ourwebsite.com/imgprodotto/product-2_big.jpg]]&gt;&lt;/g:image_link&gt;
     &lt;g:sale_price&gt;143.91 EUR&lt;/g:sale_price&gt;
     &lt;g:price&gt;159.90 EUR&lt;/g:price&gt;
     &lt;g:shipping_weight&gt;8.0 kg&lt;/g:shipping_weight&gt;
     &lt;g:product_type&gt;&lt;![CDATA[Product #2 category]]&gt;&lt;/g:product_type&gt;
     &lt;g:availability&gt;in stock&lt;/g:availability&gt;
     &lt;g:availability_date&gt;2022-08-10T00:00-0000&lt;/g:availability_date&gt;
     &lt;qty&gt;1&lt;/qty&gt;
     &lt;g:payment_accepted&gt;Visa&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;MasterCard&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;CartaSi&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;Aura&lt;/g:payment_accepted&gt;
     &lt;g:payment_accepted&gt;PayPal&lt;/g:payment_accepted&gt;
    &lt;/item&gt;
    ...
   &lt;/channel&gt;
  &lt;/rss&gt;
  </code></pre>
  <p>I need to produce a XML file purged from all the tags inside <code>&lt;item&gt;</code> except for <code>&lt;g:mpn&gt;</code>, <code>&lt;link&gt;</code>, <code>&lt;g:sale_price&gt;</code> and <code>&lt;qty&gt;</code>.</p>
  <p>In the example above, the result should be</p>
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
  &lt;rss version=&quot;2.0&quot; xmlns:g=&quot;http://base.google.com/ns/1.0&quot;&gt;
   &lt;channel&gt;
    &lt;title&gt;E-commerce's products.&lt;/title&gt;
    &lt;description&gt;&lt;![CDATA[Clothing and accessories.]]&gt;&lt;/description&gt;
    &lt;link&gt;https://www.ourwebsite.com/&lt;/link&gt;
    &lt;item&gt;
     &lt;g:mpn&gt;&lt;![CDATA[5643785645]]&gt;&lt;/g:mpn&gt;
     &lt;link&gt;&lt;![CDATA[https://www.ourwebsite.com/product_1_url.htm?mid=62367]]&gt;&lt;/link&gt;
     &lt;g:sale_price&gt;29.25 EUR&lt;/g:sale_price&gt;
     &lt;qty&gt;3&lt;/qty&gt;
    &lt;/item&gt;
    &lt;item&gt;
     &lt;g:mpn&gt;&lt;![CDATA[573489547859]]&gt;&lt;/g:mpn&gt;
     &lt;link&gt;&lt;![CDATA[https://www.ourwebsite.com/product_2_url.htm?mid=168192]]&gt;&lt;/link&gt;
     &lt;g:sale_price&gt;143.91 EUR&lt;/g:sale_price&gt;
     &lt;qty&gt;1&lt;/qty&gt;
    &lt;/item&gt;
    ...
   &lt;/channel&gt;
  &lt;/rss&gt;
  </code></pre>
  <p>I've looked at SimpleXML, DOMDocument, XPath docs but I couldn't find the way to exclude specific elements. I don't want to select by name the nodes I have to delete, as in a future Google could add some nodes and they will not be deleted by my script.</p>
  <p>I've also tried to loop through namespaced elements with SimpleXML and unset them if not matched with the nodes I have to keep:</p>
  <pre class="lang-php prettyprint-override"><code>$g = $element-&gt;children($namespaces['g']); //$element is the SimpleXMLElement of &lt;item&gt; tag
  foreach ($g as $gchild) {
      if ($gchild-&gt;getName() != &quot;mpn&quot;) {  //for example
          unset($gchild);
      }
  }
  </code></pre>
  <p>but the code above doesn't remove all nodes except for <code>&lt;g:mpn&gt;</code>, for example.</p>
  <p>PS: consider the fact that the XML contains both namespaced and not namespaced elements</p>
  <p>Thank you in advance.</p>
  <p><strong>EDIT:</strong>
  I've managed to do this with the following code:</p>
  <pre class="lang-php prettyprint-override"><code>$elementsToKeep = array(&quot;mpn&quot;, &quot;link&quot;, &quot;sale_price&quot;, &quot;qty&quot;);
  
  $domdoc = new DOMDocument();
  $domdoc-&gt;preserveWhiteSpace = FALSE;
  $domdoc-&gt;formatOutput = TRUE;
  $domdoc-&gt;loadXML($myXMLDocument-&gt;asXML());  //$myXMLDocument is the SimpleXML document related to the original XML
  $xpath = new DOMXPath($domdoc);
  
  foreach ($element-&gt;children() as $child) {
      $cname = $child-&gt;getName();
      if (!in_array($cname, $elementsToKeep)) {
          foreach($xpath-&gt;query('/rss/channel/item/'.$cname) as $node) {
              $node-&gt;parentNode-&gt;removeChild($node);
          }
      }
  }
  
  $g = $element-&gt;children($namespaces['g']);
  foreach ($g as $gchild) {
      $gname = $gchild-&gt;getName();
      if (!in_array($gname, $elementsToKeep)) {
          foreach($xpath-&gt;query('/rss/channel/item/g:'.$gname) as $node) {
              $node-&gt;parentNode-&gt;removeChild($node);
          }
      }
  }
  </code></pre>
  <p>I've used DOMDocument and DOMXPath and two loops on no-namespaced tags and namespaced tags, in order to use the <code>removeChild</code> function of DOMDocument.</p>
  <p>Really there is not a cleaner solution?? Thanks again</p>