Sorting child elements with lxml based on attribute value
<p>I'm trying to sort some child elements in a document based on an attribute value, and while the actual sorted function seems to be working, the splicing of the newly sorted elements doesn't seem to be.</p>

<pre><code>from lxml import etree

def getkey(elem):
    # Used for sorting elements by @LIN.
    # returns a tuple of ints from the exploded @LIN value
    # '1.0' -&gt; (1,0)
    # '1.0.1' -&gt; (1,0,1)
    return tuple([int(x) for x in elem.get('LIN').split('.')])

xml_str = """&lt;Interface&gt;
                &lt;Header&gt;&lt;/Header&gt;
                &lt;PurchaseOrder&gt;
                    &lt;LineItems&gt;
                        &lt;Line LIN="2.0"&gt;&lt;/Line&gt;
                        &lt;Line LIN="3.0"&gt;&lt;/Line&gt;
                        &lt;Line LIN="1.0"&gt;&lt;/Line&gt;
                    &lt;/LineItems&gt;
                &lt;/PurchaseOrder&gt;
            &lt;/Interface&gt;"""

root = etree.fromstring(xml_str)
lines = root.findall("PurchaseOrder/LineItems/Line")
lines[:] = sorted(lines, key=getkey)
res_lines = [x.get('LIN') for x in lines]
print res_lines

print etree.tostring(root, pretty_print=True)
</code></pre>

<p>When I execute the above code I will see the <code>lines</code> list did sort correctly as it prints <code>['1.0', '2.0', '3.0']</code>. However the XML tree isn't updated as tostring() prints out the below.</p>

<pre><code>&lt;Interface&gt;
  &lt;Header/&gt;
  &lt;PurchaseOrder&gt;
    &lt;LineItems&gt;
      &lt;Line LIN="2.0"/&gt;
      &lt;Line LIN="3.0"/&gt;
      &lt;Line LIN="1.0"/&gt;
    &lt;/LineItems&gt;
  &lt;/PurchaseOrder&gt;
&lt;/Interface&gt;
</code></pre>

<p>I got the idea for how to sort from <a href="http://effbot.org/zone/element-sort.htm" rel="noreferrer">http://effbot.org/zone/element-sort.htm</a>, which says that the splicing should be all that I need to update the element order, but that doens't seem to be the case. I realise lxml is not 100% compatible with elementtree, so as a sanity check I replaced the lxml import with elementtree and got the exact same results.</p>