Voir le flux RSS

autran

[Actualité] Charger des objets en Python depuis un fichier XML

Note : 2 votes pour une moyenne de 5,00.
par , 01/04/2017 à 12h30 (854 Affichages)
Dans ce billet, je vous propose un petit composant que j'ai écrit sous la forme d'une classe très courte pour charger un catalogue d'objets depuis un fichier XML.

J'ai pris le parti d'utiliser la bibliothèque standard de manipulation XML lxml pour me faciliter la tâche. Cette librairie s'installe directement avec la commande pip install lxml depuis toute station Unix ou Windows connectée à internet (nano PC de type raspberry compris).
Voici le fichier XML que je vais parser :
Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
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
<?xml version="1.0" encoding="UTF-8"?>
<clients>
    <client>
        <nom>
            Ponsable
        </nom>
        <prenom>
            Thérèse
        </prenom>
        <email>
            "therese.ponsable@dumatos.org"
        </email>
        <tel>
            "01020304"
        </tel>
    </client>
     <client>
        <nom>
            Rambo
        </nom>
        <prenom>
            John
        </prenom>
        <email>
            "rambo@biscotos.org"
        </email>
        <tel>
            "12356498"
        </tel>
    </client>
    <client>
        <nom>
            Rocky
        </nom>
        <prenom>
            Balboa
        </prenom>
        <email>
            "Rocky@baston.org"
        </email>
        <tel>
            "12356498"
        </tel>
    </client>
    <client>
        <nom>
            Starsky
        </nom>
        <prenom>
            David
        </prenom>
        <email>
            "david.starsky@guignols.org"
        </email>
        <tel>
            "12356498"
        </tel>
    </client>
</clients>
On remarque que le catalogue de clients est sous le tag <clients> et que chaque client possède un nom, un prenom, un email et un telephone. J'ai choisi de composer des entités XML à partir d'Element XML, mais j'aurais tout aussi bien pu utiliser des attributs. La discussion autour du choix entre attribut et élément restera en dehors du scope de ce billet.
L'objectif de mon chargeur est de créer une liste d'objets Client depuis cette source XML.
Voici le code source de ma classe Client :
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
class Client :
    rang = 0
    def __init__(self, nom, prenom, email, tel):
        Client.rang += 1
        self.ident = Client.rang
        self.nom = nom
        self.prenom = prenom
        self.email = email
        self.tel = tel
 
    def afficher(self):
        print(str(self.ident) + " " + self.nom + " " + self.prenom + " " + self.email + " " + self.tel)
J'ai logiquement ajouté à cet objet une méthode qui lui permet de s'afficher. Je l'ai également équipé d'un attribut static rang initialisé à 0 qui s'incrémente à la construction de chaque nouvelle instance, pour servir d'index dans ma collection.
Voici enfin le code source de mon composant :
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Carnet :
    def  __init__(self):
        self.clients = list()
 
    def ajouter(self, client):
        self.clients.append(client)
 
    def afficher(self):
        for client in self.clients:
            client.afficher()
 
    def charger(self, nomFichier):
        tree = etree.parse(nomFichier)
        for client in tree.xpath("/clients/client"):
            self.ajouter(Client(client.find("nom").text, client.find("prenom").text, client.find("email").text, client.find("tel").text))
Je n'utilise qu'un objet de la bibliothèque lxml : la classe etree qui me permet de parser un fichier XML et de mapper l'ensemble des éléments de mon fichier XML dans une collection Python, comme le font les langages modernes (pour feignants) tels que PowerShell.
Pour le test, il suffit de charger le fichier et de l'afficher de cette façon :
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
carnet = Carnet()
carnet.charger("clients.xml")
carnet.afficher()
Attention, cette petite classe est un composant de dev à modifier pour les besoins de chacun, mais ne constitue en aucun cas une source utilisable en production. En effet, aucun test de validité des valeurs du fichier XML n'est réalisé au chargement.

Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog Viadeo Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog Twitter Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog Google Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog Facebook Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog Digg Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog Delicious Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog MySpace Envoyer le billet « Charger des objets en Python depuis un fichier XML » dans le blog Yahoo

Mis à jour 03/04/2017 à 01h54 par Malick SECK (orthographe)

Tags: python 3, xml
Catégories
Programmation , Python

Commentaires

  1. Avatar de Aurelien.Regat-Barrel
    • |
    • permalink
    Hello,

    C'est l'occasion de montrer ce qui m'a poussé à basculer vers Go au lieu de Python. En effet, ce genre de marshaling est géré automatiquement par Go:

    Code go : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type Client struct {
        Name    string `xml:"nom"`
        Surname string `xml:"prenom"`
        Email   string `xml:"email"`
        Phone   string `xml:"tel"`
    }
    type Clients struct {
        Clients []Client `xml:"client"`
    }
    func ChargerClients(data []byte) (Clients, error) {
        clients := Clients{}
        err := xml.Unmarshal(data, &clients)
        return clients, err
    }

    Exemple d'appel :

    Code go : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    func main() {
        data, err := ioutil.ReadFile("clients.xml")
        if err != nil {
            log.Fatalln(err)
        }
        clients, err := ChargerClients(data)
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Println(clients)
    }

    Ca marche aussi pour du json ou du bson (MongoDB)!
  2. Avatar de autran
    • |
    • permalink
    Merci Aurélien pour le code source
    C'est vrai également pour d'autres langages récents. Un camarade vient de me montrer comment faire quelque chose de similaire en PowerShell pour charger une config depuis excel et paramétrer 30 VLAN sur un stack de switch CISCO en un clin d’œil