1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
# -*- coding: utf-8 -*-
from xml.etree import cElementTree as etree # Oui, c'est cacabeurk, mais j'ai l'habitude d'utiliser la bibliothèque lxml
dirty_dict = \
{
'IdBloc1': {
'action': '', 'cves': ['CVE-1','CVE-N'],'descritpion': "", 'id': 'IdBloc1', 'isummary': '',
'releases': {
'NomReleases1': {
'archs': {
'amd64': {
'urls': {
'http://source': {'md5': '', 'size': 0 }
}
},
'i386': {'http://i386': {'md5': '', 'size': 55 }},
'N': {'http://N': {'md5': '', 'size': 75, }}
},
'binaries': {'NomBinaries1': {'version': ''}, 'NomBinariesN': {'version': ''}},
'sources': {'': {'description': '','version': ''}}
},
},
'summary': '',
'timestamp': 128,
'title': ''
},
}
class Node(object):
def __init__(self, name, data):
"""
Objet noeud représentant un dictionnaire. Il sérialise au fur et à mesure
ses items en xml, et crée d'autres noeuds si un item est lui-même un dictionnaire
PARAMETERS
----------
name : str
Le nom du noeud. Il peut servir à indiquer le type de balise xml.
data : any
La valeur à traiter. Elle peut être de n'importe quel type.
"""
self.name = name
# Ici, on récupère le nom de la fonction qui sera appelé pour traiter le data
# Si il n'y a pas de fonction pré-défini, on appelle une fonction par défaut
self.func = getattr(self, 'ev_' + type(data).__name__, self.ev_default)
print("Création du noeud %r appelant %r" % (self.name, self.func.__name__))
# Petit exemple de traitement pour obtenir un nom de balise différent
if name.startswith('http://'):
self.xml = etree.Element("url")
else:
self.xml = etree.Element("node")
self.xml.set('name', self.name)
# On appelle la fonction
self.func(data)
def ev_dict(self, dict_):
# La donnée traité est un dict. Donc, on itère sur chaque item, et on
# crée autant de noeuds enfant que nécéssaire.
for key, item in dict_.iteritems():
child = Node(key, item)
self.xml.append(child.xml)
def ev_int(self, int_):
child = etree.SubElement(self.xml, "integer")
child.text = str(int_)
print(' Ceci est un int : %i' % int_)
def ev_default(self, data):
# Fonction par défaut
child = etree.SubElement(self.xml, "UNDEFINED")
child.text = str(data or None) # Pour éviter d'avoir une balise auto-fermante
print(' Ceci est UNDEFINED : %r' % data)
root = Node('dirty_dict', dirty_dict)
with open("dirty_dict.xml", 'w') as f:
f.write(etree.tostring(root.xml)) |
Partager