Last active
May 30, 2024 10:58
-
-
Save reimund/5435343 to your computer and use it in GitHub Desktop.
Simple dictionary to xml serializer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Simple xml serializer. | |
@author Reimund Trost 2013 | |
Example: | |
mydict = { | |
'name': 'The Andersson\'s', | |
'size': 4, | |
'children': { | |
'total-age': 62, | |
'child': [ | |
{ 'name': 'Tom', 'sex': 'male', }, | |
{ | |
'name': 'Betty', | |
'sex': 'female', | |
'grandchildren': { | |
'grandchild': [ | |
{ 'name': 'herbert', 'sex': 'male', }, | |
{ 'name': 'lisa', 'sex': 'female', } | |
] | |
}, | |
} | |
] | |
}, | |
} | |
print(dict2xml(mydict, 'family')) | |
Output: | |
<family name="The Andersson's" size="4"> | |
<children total-age="62"> | |
<child name="Tom" sex="male"/> | |
<child name="Betty" sex="female"> | |
<grandchildren> | |
<grandchild name="herbert" sex="male"/> | |
<grandchild name="lisa" sex="female"/> | |
</grandchildren> | |
</child> | |
</children> | |
</family> | |
""" | |
def dict2xml(d, root_node=None): | |
wrap = False if None == root_node or isinstance(d, list) else True | |
root = 'objects' if None == root_node else root_node | |
root_singular = root[:-1] if 's' == root[-1] and None == root_node else root | |
xml = '' | |
children = [] | |
if isinstance(d, dict): | |
for key, value in dict.items(d): | |
if isinstance(value, dict): | |
children.append(dict2xml(value, key)) | |
elif isinstance(value, list): | |
children.append(dict2xml(value, key)) | |
else: | |
xml = xml + ' ' + key + '="' + str(value) + '"' | |
else: | |
for value in d: | |
children.append(dict2xml(value, root_singular)) | |
end_tag = '>' if 0 < len(children) else '/>' | |
if wrap or isinstance(d, dict): | |
xml = '<' + root + xml + end_tag | |
if 0 < len(children): | |
for child in children: | |
xml = xml + child | |
if wrap or isinstance(d, dict): | |
xml = xml + '</' + root + '>' | |
return xml | |
Thanks for the great code! Would you mind adding a license? I want to make sure everything is in order if I use it.
Thank You Very Much.. I made a small modification to attributes to be accepted starting with @.
Example: dict2xml(d, "NFe")
{
'infNFe':
{'@versao': '3.10', '@Id': '35150469012656000120550030000783031122216144',
'ide': {
'mod', '55', 'serie', '3', 'nNF', '78303', 'dhEmi', '20/04/2015T15:36:3603:00',
'dhSaiEnt', '21/04/2015T15:36:3603:00', 'idDest', '1', 'indFinal', '0', 'indPres', '9',
'procEmi', '0', 'verProc', '61000', 'tpEmis', '1', 'finNFe', '1', 'natOp', 'SAIDA', 'tpNF', '1', 'indPag', '0'
}
}
}
<NFe>
<infNFe versao="3.10" Id="35150469012656000120550030000783031122216144">
<ide>
<mod>55</mod>
<tpNF>1</tpNF>
<idDest>1</idDest>
<indFinal>0</indFinal>
<dhEmi>20/04/2015T15:36:3603:00</dhEmi>
<natOp>SAIDA</natOp>
<indPres>9</indPres>
<tpEmis>1</tpEmis>
<nNF>78303</nNF>
<serie>3</serie>
<procEmi>0</procEmi>
<indPag>0</indPag>
<verProc>61000</verProc>
<dhSaiEnt>21/04/2015T15:36:3603:00</dhSaiEnt>
<finNFe>1</finNFe>
</ide>
</infNFe>
</NFe>
def dict2xml(d, root_node=None):
wrap = False if None == root_node or isinstance(d, list) else True
root = 'objects' if None == root_node else root_node
root_singular = root[:-1] if 's' == root[-1] and None == root_node else root
xml = ''
attr = ''
children = []
if isinstance(d, dict):
# print(d)
for key, value in dict.items(d):
if isinstance(value, dict):
children.append(dict2xml(value, key))
elif isinstance(value, list):
children.append(dict2xml(value, key))
elif key[0] == '@':
attr = attr + ' ' + key[1::] + '="' + str(value) + '"'
else:
xml = '<' + key + ">" + str(value) + '</' + key + '>'
children.append(xml)
else:
#if list
for value in d:
children.append(dict2xml(value, root_singular))
end_tag = '>' if 0 < len(children) else '/>'
if wrap or isinstance(d, dict):
xml = '<' + root + attr + end_tag
if 0 < len(children):
for child in children:
xml = xml + child
if wrap or isinstance(d, dict):
xml = xml + '</' + root + '>'
return xml
Thanks @thomaswpp, your modify fit my problem.
It's quite simple, and enough for simple situations. I like simple code.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
change line 59 to avalid unicode error: