title: Removing XML Elements Based On Attribute Value Using Python Element Tree
body: <p>I've been working with this much of the day but haven't been able to find a solution. I have a fairly large XML file that I need to strip of some data. The 'fields' are annotated using attributes by Id (field name) and Num (unique number for the field name). </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Data&gt;
      &lt;Item Id="Type" Num="30"&gt;3&lt;/Item&gt;
      &lt;Item Id="Version" Num="50"&gt;180&lt;/Item&gt;
      &lt;Owner&gt;
          &lt;Item Id="IdNumber" Num="20"&gt;00000000&lt;/Item&gt;
          &lt;Item Id="race1" Num="160"&gt;01&lt;/Item&gt;
          &lt;Item Id="race2" Num="161"&gt;88&lt;/Item&gt;
          &lt;Item Id="race3" Num="162"&gt;88&lt;/Item&gt;
          &lt;Dog&gt;
              &lt;Item Id="Breed" Num="77"&gt;Mutt&lt;/Item&gt;
              &lt;Item Id="Weight" Num="88"&gt;88&lt;/Item&gt;
          &lt;/Dog&gt;
          &lt;Dog&gt;
              &lt;Item Id="Breed" Num="77"&gt;Retriever&lt;/Item&gt;
              &lt;Item Id="Weight" Num="88"&gt;77&lt;/Item&gt;
          &lt;/Dog&gt;
      &lt;/Owner&gt;
      &lt;Owner&gt;
          &lt;Item Id="IdNumber" Num="20"&gt;00033000&lt;/Item&gt;
          &lt;Item Id="race1" Num="160"&gt;03&lt;/Item&gt;
          &lt;Item Id="race2" Num="161"&gt;88&lt;/Item&gt;
          &lt;Item Id="race3" Num="162"&gt;88&lt;/Item&gt;
          &lt;Dog&gt;
              &lt;Item Id="Breed" Num="77"&gt;Poodle&lt;/Item&gt;
              &lt;Item Id="Weight" Num="88"&gt;21&lt;/Item&gt;
          &lt;/Dog&gt;
      &lt;/Owner&gt;
  &lt;/Data&gt;
  </code></pre>
  
  <p>Here's the pretty simple python code that I assumed would do the trick, but it's stripping out the data as expected.</p>
  
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python3
  
  import xml.etree.ElementTree as ET
  
  # list of "Nums" to drop from each Owner and Dog
  drops = ['160', '161', '162', '88']
  
  # read in XML file
  with open('dogowners.xml') as xmlin:
      tree = ET.parse(xmlin)
      root = tree.getroot()
      for x in root:
          for y in x:
              # checking to make sure it's an Owner
              if y.attrib:
                  # if the value for attribute Num is in the list of drops then remove it
                  if y.attrib["Num"] in drops:
                      x.remove(y)
  
  # finally output new tree
  tree.write('output.xml')
  </code></pre>
  
  <p>output.xml</p>
  
  <p>The issue I'm running into is it's not removing all the drops/Nums listed. In the case with this small XML, it's only doing the first and third value on the Owner level, which is consistent with my large file because it appears to be only removing every other one.</p>
  
  <pre><code>&lt;Data&gt;
      &lt;Item Id="Type" Num="30"&gt;3&lt;/Item&gt;
      &lt;Item Id="Version" Num="50"&gt;180&lt;/Item&gt;
      &lt;Owner&gt;
          &lt;Item Id="IdNumber" Num="20"&gt;00000000&lt;/Item&gt;
          &lt;Item Id="race2" Num="161"&gt;88&lt;/Item&gt;
          &lt;Dog&gt;
              &lt;Item Id="Breed" Num="77"&gt;Mutt&lt;/Item&gt;
              &lt;Item Id="Weight" Num="88"&gt;88&lt;/Item&gt;
          &lt;/Dog&gt;
          &lt;Dog&gt;
              &lt;Item Id="Breed" Num="77"&gt;Retriever&lt;/Item&gt;
              &lt;Item Id="Weight" Num="88"&gt;77&lt;/Item&gt;
          &lt;/Dog&gt;
      &lt;/Owner&gt;
      &lt;Owner&gt;
          &lt;Item Id="IdNumber" Num="20"&gt;00033000&lt;/Item&gt;
          &lt;Item Id="race2" Num="161"&gt;88&lt;/Item&gt;
          &lt;Dog&gt;
              &lt;Item Id="Breed" Num="77"&gt;Poodle&lt;/Item&gt;
              &lt;Item Id="Weight" Num="88"&gt;21&lt;/Item&gt;
          &lt;/Dog&gt;
      &lt;/Owner&gt;
  &lt;/Data&gt;
  </code></pre>
  
  <p>I feel like I might be missing something kind of obvious, but XML parsing is not my forte and I've been fighting with this for a couple of hours. Any help is greatly appreciated.</p>