IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

DOM Parsage XML et fonction récursive


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 788
    Points : 446
    Points
    446
    Par défaut DOM Parsage XML et fonction récursive
    Bonjour

    Comme souvent, je bute sur la création d'une fonction récursive

    Mon but est de parser un fichier xml et d'enregistrer les informations contenu dans ce fichier tout en gardant la hiérarchie des "objets" du fichier XML

    Pour mieux comprendre, prenons un exemple de XML
    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
    <Structure>
        <Object>Objet 1</Object>
        <Children>
            <Structure>
                <Object>Objet 1.1</Object>
            </Structure>
            <Structure>
                <Object>Objet 1.2</Object>
                <Children>
                    <Structure>
                         <Object>Objet 1.2.1</Object>
                     </Structure>
                 </Children>
            </Structure>
        </Children>
    </Structure>

    Donc une structure à un objet parent qui peut avoir des enfants. Ces enfants peuvent eux même avoir des enfants
    Mon but est donc de récupérer ces informations dans des objets python tout en conservant la hiérachie
    J'ai donc pense avoir un dictionnaire avec pour clé le parent et pour valeur la liste des enfants (qui contiendra un dictionnaire si elle n'est pas vide)
    Je suis libre de choisir la structure python pour cela donc n'hésitez pas à me proposer autre chose si besoin

    Dans notre exemple, le résultat que j'ai imaginé sera le suivant :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    { Objet 1 : [ {Objet 1.1 : [ ] ,  Objet 1.2 : [ { Objet 1.2.1 : [] } ] ] }

    Pour ce faire, j'ai créé une fonction que voici :
    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
    def GetChildren(structure):   
            childList = []    
            objRef = ''
            for node in structure.childNodes:
                if node.nodeType == minidom.Node.ELEMENT_NODE and node.nodeName == "Object":
                    objRef = node.childNodes[1].firstChild.data.encode("mbcs")
                elif node.nodeType == minidom.Node.ELEMENT_NODE and node.nodeName == "Children" :
                    for child in node.childNodes:
                        if child.nodeType == minidom.Node.ELEMENT_NODE and child.nodeName ==  "Structure":                    
                            childList.append(child.childNodes[1].childNodes[1].firstChild.data.encode("mbcs"))
                            r = GetChildren(child)
            return {objRef : childList}
     
    print GetChildren((structure)

    Mon problème est le suivant ; je ne récupère que les fils directs de Objet 1 (donc Objet 1.1 et Objet 1.2) alors que je parcours ma fonction en pas à pas, je vois bien que dans childList, la valeur Objet 1.2.1 est présente mais je la perd tout à la fin

    Ca doit être une petite bêtise mais je vois pas ou
    Le savoir est une arme alors soyons armés

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Si le sujet est de parcourir une hiérarchie d'éléments XML, pourquoi ne pas essayer de comprendre avec une structure beaucoup plus simple:
    Code : 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
    XML = '''<document>
    <object ident="objet 1">
        <object ident="objet 1.1"/>
        <object ident="objet 1.2">
            <object ident="objet 1.2.1"/>
        </object>
    </object>
    </document>
    '''
     
    from xml.etree import ElementTree as ET
     
    def show_objects(node, level=0):
        for e in node.findall('./object'):
            print ('*' * (4*level), e.attrib['ident'])
            show_objects(e, level=level+1)
     
    tree = ET.fromstring(XML)
    show_objects(tree)
    Pour ce qui est de reconstruire cette structure dans des dicts emboîtés, c'est une variation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def map_objects(node, level=0):
        map = {}
        for e in node.findall('./object'):
            print ('*' * (4*level), e.attrib['ident'])
            children = map_objects(e, level=level+1)
            ident = e.attrib['ident']
            map[ident] = children
        return map    
     
    print (map_objects(tree))
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 788
    Points : 446
    Points
    446
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Si le sujet est de parcourir une hiérarchie d'éléments XML, pourquoi ne pas essayer de comprendre avec une structure beaucoup plus simple:
    Bonjour et merci pour ta réponse et ton aide

    J'utilise cette structure complexe de XML tout simplement parce qu'elle m'est imposée
    De plus, j'aimerai continuer à utilise minidom par souci d'harmonisation avec le reste du code.

    Cela ne m'a pas empêché de m'inspirer de ton code pour améliorer le mien et j'y suis presque :

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def GetChildren(structure):   
            map = {} 
            objRef = ''
            for node in structure.childNodes:
                if node.nodeType == minidom.Node.ELEMENT_NODE and node.nodeName == "Objet":
                    objRef = node.childNodes[1].firstChild.data.encode("mbcs")
                elif node.nodeType == minidom.Node.ELEMENT_NODE and node.nodeName == "CHILDREN":
                    for child in node.childNodes:
                        if child.nodeType == minidom.Node.ELEMENT_NODE and child.nodeName == "Structure":                        
                            #childList.append(child.childNodes[1].childNodes[1].firstChild.data.encode("mbcs"))
                            children = GetChildren(child)
                            map[child.childNodes[1].childNodes[1].firstChild.data.encode("mbcs")] = children
            return map

    Le seul problème est que je n'ai pas les premiers Objets (dans l'exemple Objet 1) . Ca me parait logique puisqu'on ajoute pas ObjRef dans le dictionnaire la première fois mais je ne vois pas comment faire
    Le savoir est une arme alors soyons armés

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Citation Envoyé par Nom Voir le message
    J'utilise cette structure complexe de XML tout simplement parce qu'elle m'est imposée
    De plus, j'aimerai continuer à utilise minidom par souci d'harmonisation avec le reste du code.
    Je me contente de prendre le temps de mettre le projecteur sur vos incompréhensions.
    Pour le reste, je pense que vous êtes assez grand pour adapter (pour peu que mes explications soient claires).

    Citation Envoyé par Nom Voir le message
    Le seul problème est que je n'ai pas les premiers Objets (dans l'exemple Objet 1) . Ca me parait logique puisqu'on ajoute pas ObjRef dans le dictionnaire la première fois mais je ne vois pas comment faire
    Mon code fonctionne parce que l'arbre est écrit comme çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    XML = '''<document>
    <object ident="objet 1">
        <object ident="objet 1.1"/>
        <object ident="objet 1.2">
            <object ident="objet 1.2.1"/>
        </object>
    </object>
    </document>
    '''
    Autrement dit le premier élément n'est pas un nœud.
    Votre arbre est plutôt écrit comme çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    XML = '''<object ident="objet 1">
        <object ident="objet 1.1"/>
        <object ident="objet 1.2">
            <object ident="objet 1.2.1"/>
        </object>
    </object>'''
    Côté code le for e in node "plongeant" direct dans le s/arbre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def show_objects(node, level=0):
        for e in node.findall('./object'):
            print ('*' * (4*level), e.attrib['ident'])
            show_objects(e, level=level+1)
    saute le premier nœud.

    Dans ce cas, il faut effectuer les traitements "avant":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def show_objects(node, level=0):
        print ('*' * (4*level), node.attrib['ident'])
        for e in node.findall('./object'):
            show_objects(e, level=level+1)
    Et vous voyez que c'est plus simple de "montrer" çà en quelques lignes bien choisies et vous laissez adapter votre code.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 788
    Points : 446
    Points
    446
    Par défaut
    Merci pour votre aide et pour votre temps,
    j'ai donc traiter le premier nœud avant et j’obtiens un résultat satisfaisant

    Merci aussi pour les exemples de code qui m'ont faciliter la compréhension
    Le savoir est une arme alors soyons armés

  6. #6
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    417
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 417
    Points : 826
    Points
    826
    Par défaut
    La récursivité (sujet intéressant et très puissant) est décrit dans les grandes largeurs ici :
    http://recursivite.developpez.com/

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par fatbob Voir le message
    La récursivité (sujet intéressant et très puissant) est décrit dans les grandes largeurs ici :
    http://recursivite.developpez.com/
    Super!
    Dommage que les parcours d'arbres y soient absents et que les exemples soient écrit en une sorte de Pascal.
    Je n'ai rien contre Pascal, c'est un langage fort vénérable.
    Mais, pour le programmeur Python, c'est un peu comme le grec ou le latin: "désuet".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    417
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 417
    Points : 826
    Points
    826
    Par défaut
    Certes.
    D'un autre côté ce n'est pas bien compliqué à traduire :-) Ce qui compte, c'est de s'exercer aux principes. Une fois compris, j'imagine que le parcours d'arbre n'est pas sorcier.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Afficher du XML dans une table HTML avec fonction récursive (ou pas)
    Par iviewclear dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 19/04/2010, 17h04
  2. [VB6] XML, fonction récursive de recherche
    Par kboo dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 24/04/2006, 21h27
  3. [DOM] Parsage XML en PHP 4
    Par Huntress dans le forum Bibliothèques et frameworks
    Réponses: 7
    Dernier message: 07/12/2005, 22h24
  4. Parsage avec la fonction eval
    Par alain31tl dans le forum Langage
    Réponses: 12
    Dernier message: 23/11/2005, 15h27
  5. [JAXB/DOM] Parser Xml : possible avec path reel et non uri !
    Par Jaxofun dans le forum Servlets/JSP
    Réponses: 7
    Dernier message: 01/08/2005, 10h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo