What is the standard way for testing if an element exists or not with lxml.objectify
?
Sample XML :
<?xml version="1.0" encoding="utf-8"?>
<Test>
<MyElement1>sdfsdfdsfd</MyElement1>
</Test>
Code
from lxml import etree, objectify
with open('config.xml') as f:
xml = f.read()
root = objectify.fromstring(xml)
print root.MyElement1
print root.MyElement17 # AttributeError: no such child: MyElement17
Then, what is the simplest solution to write something on a specific path ?
root.MyElement1.Blah = 'New' # this works because MyElement1 already exists
root.MyElement17.Blah = 'New' # this doesn't work because MyElement17 doesn't exist
root.MyElement1.Foo.Bar = 'Hello' # this doesn't as well... How to do this shortly ?
In lxml. objectify, this directly translates to enforcing a specific object tree, i.e. expected object attributes are ensured to be there and to have the expected type. This can easily be achieved through XML Schema validation at parse time.
lxml. etree supports parsing XML in a number of ways and from all important sources, namely strings, files, URLs (http/ftp) and file-like objects. The main parse functions are fromstring() and parse(), both called with the source as first argument.
lxml is a Python library which allows for easy handling of XML and HTML files, and can also be used for web scraping. There are a lot of off-the-shelf XML parsers out there, but for better results, developers sometimes prefer to write their own XML and HTML parsers.
find
method will return None
if the element does not exist.
>>> xml = '''<?xml version="1.0" encoding="utf-8"?>
... <Test>
... <MyElement1>sdfsdfdsfd</MyElement1>
... </Test>'''
>>>
>>> from lxml import objectify
>>> root = objectify.fromstring(xml)
>>> root.find('.//MyElement1')
'sdfsdfdsfd'
>>> root.find('.//MyElement17')
>>> root.find('.//MyElement17') is None
True
UPDATE according to the question edit:
>>> from lxml import objectify
>>>
>>> def add_string(parent, attr, s):
... if len(attr) == 1:
... setattr(parent, attr[0], s)
... else:
... child = getattr(parent, attr[0], None)
... if child is None:
... child = objectify.SubElement(parent, attr[0])
... add_string(child, attr[1:], s)
...
>>> root = objectify.fromstring(xml)
>>> add_string(root, ['MyElement1', 'Blah'], 'New')
>>> add_string(root, ['MyElement17', 'Blah'], 'New')
>>> add_string(root, ['MyElement1', 'Foo', 'Bar'], 'Hello')
>>>
>>> root.MyElement1.Blah
'New'
>>> root.MyElement17.Blah
'New'
>>> root.MyElement1.Foo.Bar
'Hello'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With