Search code examples
pythonlxmllxml.objectify

Convert a dot notation string to object to access lxml objects python


I am trying to update the xml using object notation using lxml objectify.

<xml>
  <fruit>
    <citrus>
        <lemon />
    </citrus>
  </fruit>  
</xml>

I am trying to add another fruit called mango using lxml objectify like

root = lxml.objectify.fromstring(xml_string)
root.fruit.citrus = 'orange'

def update(path, value):
    // code

update('fruit.citrus', 'orange')

I would like to pass a string like 'fruit.citrus' because I cannot pass an object fruit.citrus.

How do I achieve this in Python ie how do I execute the code 'root.fruit.citrus = 'orange' inside the update function. How to convert string to object?


Solution

  • Try Below solution:

    import lxml.objectify, lxml.etree
    
    xml = '<xml>  <fruit>    <citrus>        <lemon />    </citrus>  </fruit> </xml>'
    
    root = lxml.objectify.fromstring(xml)
    
    print("Before:")
    print(lxml.etree.tostring(root))
    
    
    def update(path, value):
        parent = None
        lst = path.split('.')
        while lst:
            ele = lst.pop(0)
            parent = getattr(root, ele) if parent is None else getattr(parent, ele)
        lxml.etree.SubElement(parent, value)
    
    
    update('fruit.citrus', 'orange')
    
    print("After:")
    print(lxml.etree.tostring(root))
    

    Output:

    Before:
    b'<xml><fruit><citrus><lemon/></citrus></fruit></xml>'
    After:
    b'<xml><fruit><citrus><lemon/><orange/></citrus></fruit></xml>'