xmltodict
xmltodict copied to clipboard
force_list with no children
Hi,
When using force_ list
on a node with no children, I would except an empty list but I get a [None]
.
Is that on purpose or is it a behavior that could be changed?
Thanks
What would be the expected output if the node with no children appeared twice, though? E.g.:
xml = """
<servers>
<server></server>
<server></server>
</servers>
"""
xmltodict.parse(xml, force_list=('server', ))
I agree that [None, None]
is not ideal but at least the list length reflects the number of input nodes.
<servers>
<server></server>
<server></server>
</servers>
may be converted to
{
"servers": {
"server": [
{
},
{
}
]
}
}
'''
If called with force_list=('interface',), it will produce
this dictionary:
{'servers':
{'server':
{'name': 'host1',
'os': 'Linux'},
'interfaces':
{'interface':
[ {'name': 'em0', 'ip_address': '10.0.0.1' } ] } } }
`force_list` can also be a callable that receives `path`, `key` and
`value`. This is helpful in cases where the logic that decides whether
a list should be forced is more complex.
'''
def push_data(self, item, key, data):
if self.postprocessor is not None:
result = self.postprocessor(self.path, key, data)
if result is None:
return item
key, data = result
if item is None:
item = self.dict_constructor()
try:
value = item[key]
if isinstance(value, list):
value.append(data)
else:
item[key] = [value, data]
except KeyError:
if self._should_force_list(key, data):
item[key] = [data]
else:
item[key] = data
return item
def _should_force_list(self, key, value):
if not self.force_list:
return False
if isinstance(self.force_list, bool):
return self.force_list
try:
return key in self.force_list
except TypeError:
return self.force_list(self.path[:-1], key, value)