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 :

Analyse fichier XML - Boucle


Sujet :

Python

  1. #1
    Futur Membre du Club
    Analyse fichier XML - Boucle
    Bonjour,

    J'ai quelques soucis concernant le traitement de fichiers xml.

    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
    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
    <?xml version='1.0' encoding='UTF-8'?>
    <BAD_MSG>
        <request-violations>
            <violation>
                <viol_index>42</viol_index>
                <viol_name>VIOL_ATTACK_SIGNATURE</viol_name>
                <context>parameter</context>
                <parameter_data>
                    <value_error/>
                    <enforcement_level>global</enforcement_level>
                    <name>bmFtZTE=</name>
                    <value>dmFsdWV2aW9sYXRpb24J</value>
                    <param_name_pattern>*</param_name_pattern>
                    <staging>0</staging>
                </parameter_data>
                <staging>0</staging>
                <sig_data>
                    <sig_id>200000073</sig_id>
                    <blocking_mask>7</blocking_mask>
                    <kw_data>
                        <buffer>Qm9uam91cjEJ</buffer>
                        <offset>38</offset>
                        <length>63</length>
                    </kw_data>
                </sig_data>
                <sig_data>
                    <sig_id>200002611</sig_id>
                    <blocking_mask>7</blocking_mask>
                    <kw_data>
                        <buffer>Qm9uam91cjI=</buffer>
                        <offset>38</offset>
                        <length>26</length>
                    </kw_data>
                </sig_data>
            </violation>
            <violation>
                <viol_index>42</viol_index>
                <viol_name>VIOL_ATTACK_SIGNATURE</viol_name>
                <context>request</context>
                <sig_data>
                    <sig_id>200011069</sig_id>
                    <blocking_mask>7</blocking_mask>
                    <kw_data>
                        <buffer>Qm9uam91cjM=</buffer>
                        <offset>62</offset>
                        <length>1</length>
                    </kw_data>
                    <kw_data>
                        <buffer>Qm9uam91cjQ=</buffer>
                        <offset>44</offset>
                        <length>16</length>
                    </kw_data>
                </sig_data>
            </violation>
            <violation>
                <viol_index>14</viol_index>
                <viol_name>VIOL_HTTP_PROTOCOL</viol_name>
                <http_sanity_checks_status>1</http_sanity_checks_status>
                <http_sub_violation_status>1</http_sub_violation_status>
            </violation>
        </request-violations>
    </BAD_MSG>


    L'objectif est de récupérer les valeur des sig_id, buffer, offset, length en fonction du <viol_name> et du <context>.

    Par exemple: quand <viol_name> = VIOL_ATTACK_SIGNATURE et que <context> = parameter je dois récupérer les sig_id (200000073, 200002611) ainsi que les buffer/offset/length qui leurs sont rattachés.
    Mais dès que le contexte passe en request il faut que je récupère le sig_id 200011069 et les buffer/offset/length qui suivent.
    Même chose quand le <viol_name> change.

    Le problème que j'ai, est que les infos ne sont pas regroupées par blocs distincts et sont au même niveau dans l'arborescence.

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    for nme in root.iter("viol_name"):   
        name = nme.text
        print(name)
     
        if name == "VIOL_ATTACK_SIGNATURE":   
     
     
            for ctx in root.iter("context"):
                context = ctx.text
     
                if context == "parameter":
                    print("Context: " + context)
     
                    for enfor in root.iter("enforcement_level"):
                        print(enfor.text)
     
                    for name in root.iter("name"):
                        namedecode = base64.b64decode(name.text).decode()
                        print(namedecode)
     
                    for val in root.iter("value"):
                        value = base64.b64decode(val.text).decode()
                        print("Value: " + value)
     
                    for data in root.iter("sig_data"):
                        print("Sig_id: " + data.findtext("sig_id"))
                        print("Blocking_mask: " + data.findtext("blocking_mask"))
                        buff = data.findtext("kw_data/buffer")
                        buffer = base64.b64decode(buff).decode()
                        print("Buffer: " + buffer)
                        print("Offset: " + data.findtext("kw_data/offset"))
                        print("Length: " + data.findtext("kw_data/length") + "\r\n")


    Le souci de mon code c'est qu'il va me sortir pour le contexte parameter tous les Sig_id/Buffer/Offset/Length du fichier et va faire la même chose pour le contexte request.

    J'ai essayé de modifié le code en mettant un while à la place de if name == "VIOL_ATTACK_SIGNATURE" et if context == "parameter" mais ça me fait une boucle infinie même quand je mets un break.



    Merci pour votre aide

  2. #2
    Expert éminent sénior
    Bonjour
    Juste pour pouvoir reproduire, tu utilises quel module xml ???
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  3. #3
    Futur Membre du Club
    Bonjour,

    J'utilise xml.etree.ElementTree.

    J'ai eu un déclic et j'ai partiellement réussi à régler le problème en modifiant mon code. Voici le nouveau:

    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
    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
    81
    82
    83
    84
    85
    86
    87
    88
    import base64                                               
    import xml.etree.ElementTree as ET
     
    tree = ET.parse('Projet\Projet_ATTACK_SIGNATURE\VIOL_ATTACK_SIGNATURE_comp.xml')
    root = tree.getroot()
     
    for data in root.iter("violation"): 
     
     
    # Elements communs      
        print("Viol_index: " + data.findtext("viol_index"))
        print("Viol_name: " + data.findtext("viol_name"))
     
        ctx = data.findtext("context")
        if ctx != None:
            print("Context: " + data.findtext("context"))
     
     
    # Context Parameter
     
        enf = data.findtext("parameter_data/enforcement_level")
        if enf != None:
            print("Enforcement_level: " + enf)
     
     
        nme = data.findtext("parameter_data/name")
        if nme != None:
            named = base64.b64decode(nme).decode(errors="ignore")
            print("Name: " + named)
     
        val = data.findtext("parameter_data/value")
        if val != None:
            value = base64.b64decode(val).decode(errors="ignore")
            print(value)
     
        panpat = data.findtext("parameter_data/param_name_pattern")
        if panpat != None:
            print("Param_name_pattern: " + panpat)
     
        stg = data.findtext("parameter_data/staging")
        if stg != None:
            print("Statging: " + data.findtext("parameter_data/staging"))
     
     
    # Context Cookie
     
        cname = data.findtext("cookie/cookie_name")
        if cname != None:
            cookie_name = base64.b64decode(cname).decode(errors="ignore")
            print("Cookie_name: " + cookie_name)
     
        cval = data.findtext("cookie/cookie_value")
        if cval != None:
            cookie_value = base64.b64decode(cval).decode(errors="ignore")
            print("Cookie_value: " + cookie_value)
     
        cpat = data.findtext("cookie/cookie_pattern")
        if cpat != None:
            print("Cookie_pattern: " + cpat)     
     
        cstg = data.findtext("cookie/staging")
        if cstg != None:
            print("Staging: " + cstg)
     
     
     
    # Context Parameter/Request/Cookie
     
        sig = data.findtext("sig_data/sig_id")
        if sig != None:
            print("Sig_id: " + sig)
     
        blck = data.findtext("sig_data/blocking_mask")
        if blck != None:
            print("Blocking_mask: " + blck)
     
        buf = data.findtext("sig_data/kw_data/buffer")
        if buf != None:
            buffer = base64.b64decode(buf).decode(errors = "ignore")
            print("Buffer: " + buffer)
     
        off = data.findtext("sig_data/kw_data/offset")
        if off != None:
            print("Offset: " + off)
     
        lgth = data.findtext("sig_data/kw_data/length")
        if lgth != None:
            print("Length: " + lgth + "\r\n")



    Je mets des if != None pour éviter que ça m'affiche None quand la balise n'existe pas.

    Un problème subsiste c'est qu'il ne me sort qu'une sig_id pour chaque contexte. Par exemple, pour le contexte parameter il me sort le sig_id 200000073 avec le buffer/offset/length qui suivent mais pas le sig_id 200002611. J'ai essayé de faire une boucle mais ça m'affiche plusieurs fois le même sig_id

    De même pour le contexte request il y a 2 fois buffer/offset/length, il ne me sort que le 1er.

  4. #4
    Rédacteur



    Ma solution :

    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
    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
    #! python3
    # coding: utf-8
     
    import xml.etree.ElementTree as ET
     
     
    with open('Tests/en_cours/datas.xml', 'r', encoding='utf-8') as xml_file:
        xml_tree = ET.parse(xml_file)
        root = xml_tree.getroot()
        request_violations = root.find('request-violations')
     
        for violation in request_violations:  # parcours des tags 'violation'
            viol_name = violation.find('viol_name')
     
            if viol_name.text == 'VIOL_ATTACK_SIGNATURE':
                context = violation.find('context')
     
                if context.text == 'parameter':
                    print(viol_name.text, context.text)
                    for child in violation:
                        if child.tag == 'sig_data':
                            sig_id = child.find('sig_id')
                            buffer = child.find('kw_data/buffer')
                            offset = child.find('kw_data/offset')
                            length = child.find('kw_data/length')
                            print(sig_id.text, buffer.text,
                                  offset.text, length.text)
                print('-----------------')
     
                if context.text == 'request':
                    """ Les context request n'ont pas la même structure """
                    print(viol_name.text, context.text)
                    sig_data = violation.find('sig_data')
                    for child in sig_data:
                        if child.tag == 'sig_id':
                            print(child.text)
                        if child.tag == 'kw_data':
                            buffer = child.find('buffer')
                            offset = child.find('offset')
                            length = child.find('length')
                            print(buffer.text, offset.text, length.text)
                print('-----------------')
     
            if viol_name == 'VIOL_HTTP_PROTOCOL':
                print(viol_name.text)

  5. #5
    Futur Membre du Club
    Merci beaucoup ça marche du tonnerre.