Python easier way to insert new items into XML sub sub elements using ElementTree
<p>I am editing a config file and would like to add new sub elements into the structure. The problem I am having is that in the config file the sub elements have the same name and I have not found a way to find the index the insert location with a .find command. An example of the config file is here:</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;ConfigurationFile&gt;
  &lt;Configuration ItemName="Parent1"&gt;
    &lt;Category ItemName="Parent2"&gt;
      &lt;Category ItemName="Parent3"&gt;
        &lt;Category ItemName="ChildLevelToAdd"&gt;
          &lt;Option ItemName="x" ValueType="6"&gt;5&lt;/Option&gt;
          &lt;Option ItemName="z" ValueType="6"&gt;0&lt;/Option&gt;
          &lt;Category ItemName="ChildCategory"&gt;
            &lt;Option ItemName="a" ValueType="1"&gt;&lt;/Option&gt;
            &lt;Option ItemName="b" ValueType="2"&gt;&lt;/Option&gt;
            &lt;Option ItemName="c" ValueType="3"&gt;
            &lt;/Option&gt;
            &lt;/Category&gt;
        &lt;/Category&gt;
      &lt;/Category&gt;
&lt;/Category&gt;
</code></pre>

<p>
</p>

<p>I am trying to add a new "ChildToAdd" category and everything that falls below it. </p>

<p>I have tried the following code to index, but it seems it is only able to locate first child elements:</p>

<pre><code>a = root.find('Configuration') #It is only possible to find sub-elements of the root
b = root.find('Category') #These generate a none type
</code></pre>

<p>The best way I have found to insert the new category element is using:</p>

<pre><code>root[0][0][0].insert(0,ET.Element("Category", ItemName = "NewChild"))
</code></pre>

<p>And then when I want to add options to this newly created category I use: </p>

<pre><code>root[0][0][0][0].insert(0,ET.Element("NewOption", ItemName = "NewVal", ValueType ="NewType"))
</code></pre>

<p>This seems like a very untidy way to do this. I am wondering if there are any cleaner methods to find and specify the insertion point for the new subsubelement (category) and its future sub-elements (options)? </p>

<p>Use XPath expression in the form of <strong><code>.//element_name</code></strong> to find element anywhere within context node (the root element in this case). For example, the following should return first instance of <code>&lt;Category&gt;</code> element, anywhere within <code>root</code> :</p>

<pre><code>root.find('.//Category') 
</code></pre>

<p>You can also find element by its attribute value using XPath. For example, the following should return <code>&lt;Category&gt;</code> element where <code>ItemName</code> attribute value equals "Parent3" :</p>

<pre><code>root.find('.//Category[@ItemName="Parent3"]')
</code></pre>

<p>ElementTree supports some other XPath syntax as documented in <a href="https://docs.python.org/2/library/xml.etree.elementtree.html#elementtree-xpath" rel="nofollow">here</a>.</p>

<hr>

<p>I'd also suggest to store your new element in a variable so that you can add child element to it later without having to query the XML again :</p>

<pre><code>c = ET.Element("Category", ItemName = "NewChild")
c.insert(0,ET.Element("NewOption", ItemName = "NewVal", ValueType ="NewType"))

p = root.find('.//Category[@ItemName="Parent3"]')
p.insert(0, c)
</code></pre>

python xml-parsing elementtree