Search code examples
pythonxmlelementtree

'lxml.etree._ElementTree' object has no attribute 'insert'


I am trying to parse through my .xml file using glob and then use etree to add more code to my .xml. However, I keep getting an error when using doc insert that says object has no attribute insert. Does anyone know how I can effectively add code to my .xml?

from lxml import etree
path = "D:/Test/"
for xml_file in glob.glob(path + '/*/*.xml'):
    doc = etree.parse(xml_file)
    new_elem = etree.fromstring("""<new_code abortExpression=""
                        elseExpression=""
                        errorIfNoMatch="false"/>""")
doc.insert(1,new_elem)
new_elem.tail = "\n"

My original xml looks like this :

<data>
  <assesslet index="Test" hash-uptodate="False" types="TriggerRuleType" verbose="True"/>
</data>

And I'd like to modify it to look like this:

<data>
<assesslet index="Test" hash-uptodate="False" types="TriggerRuleType" verbose="True"/>
<new_code abortExpression="" elseExpression="" errorIfNoMatch="false"/>
</data>

Solution

  • The problem is that you need to extract the root from your document before you can start modifying it: modify doc.getroot() instead of doc.

    This works for me:

    from lxml import etree
    xml_file = "./doc.xml"
    doc = etree.parse(xml_file)
    new_elem = etree.fromstring("""<new_code abortExpression=""
                                elseExpression=""
                                errorIfNoMatch="false"/>""")
    root = doc.getroot()
    root.insert(1, new_elem)
    new_elem.tail="\n"
    

    To print the results to a file, you can use doc.write():

    doc.write("doc-out.xml", encoding="utf8", xml_declaration=True)
    

    Note the xml_declaration=True argument: it tells doc.write() to produce the <?xml version='1.0' encoding='UTF8'?> header.