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

XSL/XSLT/XPATH XML Discussion :

Tester la présence de balises et repérer plusieurs sous-éléments


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 28
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 7
    Points : 6
    Points
    6
    Par défaut Tester la présence de balises et repérer plusieurs sous-éléments
    Bonsoir,
    J'ai un souci avec mon programme qui est censé tester la présence de balises. Voici le document 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
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <root>
    	<test>
    		<Cell>
    				<Data Type="Number">1</Data>
    		</Cell>
    		<Cell ssStyleID="s181">
    				<Data Type="String">perso A</Data>
    		</Cell>
    		<Cell>
    				<ssData>
    					<a><Font>et</Font></a>
    					<children type="me" value="3"/>
                                   </ssData>
    			</Cell>
    		</test>
     
    	  <test>
    			<Cell>
    				<Data Type="Number">2</Data>
    			</Cell>
    			<Cell>
    				<Data Type="String">perso B</Data>
    			</Cell>
    			<Cell>
    					<ssData>
    					         <children type="me"/>
                                            </ssData>
    			</Cell>
    	  </test>
     
    	  <test>
    			<Cell>
    				<Data Type="Number">3</Data>
    			</Cell>
    			<Cell>
    				<Data Type="String">perso A</Data>
    			</Cell>
    			<Cell><ssData>
    				<a><Font>Small</Font></a>
                                    <a><Font>mais</Font></a>
    				<children type="me" value="3"/></ssData>
    			</Cell>
    	  </test>
    </root>
    Mon programme parvient à tester la présence des balises, mais il ne me repère ensuite que le première balise <a> de chaque <test>:

    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
    import re
    import sys
    import xml.etree.ElementTree as ET
     
    fichier= ("TestPrésence.xml")
    tree = ET.parse(fichier)
    root = tree.getroot()
     
    for test in root.findall(".//test"):
        for ssdata in test.iter('ssData'):
            balisea = ssdata.find('a')
            if balisea is None:
                print ("mot:", "NA")
                continue
            for font in balisea.iter('Font'):
                print ("mot:", font.text)
    J'ai essayé de modifier balisea = ssdata.find('a') en balisea = ssdata.findall('a'), mais ça m'affiche en sortie du programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      File "CountBalisesA.py", line 33, in <module>
        for font in balisea.iter('Font'):
    AttributeError: 'list' object has no attribute 'iter'
    D'où vient le problème?
    Merci!

  2. #2
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 842
    Points : 6 522
    Points
    6 522
    Par défaut
    Citation Envoyé par Choopoo Voir le message
    J'ai un souci avec mon programme qui est censé tester la présence de balises.
    De quelles balises parles-tu? Explique ce que tu cherches à faire.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  3. #3
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 842
    Points : 6 522
    Points
    6 522
    Par défaut
    Je crois savoir ce qui ne va pas. Lorsque tu utilises la méthode findall(), elle renvoie non pas un objet Element, mais une liste d'objets Element (c'est ce que te signale le message d'erreur), or une liste n'a pas de méthode iter() contrairement à un objet Element. Tu dois donc boucler sur ta liste pour obtenir des objets Element et exploiter les méthodes et propriétés qui leurs sont propres.

    Personnellement, j'écrirai ce bout de code de cette manière:
    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
    import xml.etree.ElementTree as ET
     
    tree = ET.parse('ssdata.xml')
    root = tree.getroot()
     
    for ssDataElt in root.findall('test//ssData'):
        aElts = ssDataElt.findall('a[Font]')
     
        if not aElts:
            print ('mot: NA')
            continue
     
        for aElt in aElts:
            print ('mot: {}'.format(aElt.find('Font').text))

    (En nommant les variables en anglais, ce qui est plus concis et qui permet d'exprimer le pluriel et le singulier de manière claire.)
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  4. #4
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Voici comment le script ressemble en suivant exactement la logique de l'op sans altérant aucunement le xpath.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for test in root.findall(".//test"):
        for ssdata in test.iter('ssData'):
            cbalisea = ssdata.findall('a')
            if len(cbalisea)==0:
                print("mot", "NA")
                continue
            for balisea in cbalisea:
                for font in balisea.iter("Font"):
                    print("mot", font.text)

  5. #5
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 28
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Merci beaucoup pour vos réponses, ça marche!

  6. #6
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 28
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Par contre, je cherche à complexifier ma recherche en ajoutant une contrainte à mon programme: ne prendre en compte QUE la première balise <Data Type="Number"> de chaque balise <test>:

    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
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <root>
    	<test>
    		<Cell>
    				<Data Type="Number">1</Data>
    		</Cell>
    		<Cell ssStyleID="s181">
    				<Data Type="String">perso A</Data>
    		</Cell>
    		<Cell>
    				<ssData>
    					<a><Font>et</Font></a>
    					<children type="me" value="3"/>
                                   </ssData>
    	         </Cell>
                     <Cell>
    				<Data Type="Number">Faux</Data>
    		</Cell>
                    <Cell>
    				<Data Type="Number">Faux</Data>
    		</Cell>
    	</test>
     
    	  <test>
    			<Cell>
    				<Data Type="Number">2</Data>
    			</Cell>
    			<Cell>
    				<Data Type="String">perso B</Data>
    			</Cell>
    			<Cell>
    					<ssData>
    					         <children type="me"/>
                                            </ssData>
    			</Cell>
    	  </test>
     
    	  <test>
    			<Cell>
    				<Data Type="Number">3</Data>
    			</Cell>
    			<Cell>
    				<Data Type="String">perso A</Data>
    			</Cell>
    			<Cell><ssData>
    				<a><Font>Small</Font></a>
                                    <a><Font>mais</Font></a>
    				<children type="me" value="3"/></ssData>
    			</Cell>
                           <Cell>
    				<Data Type="Number">Faux</Data>
    		       </Cell>
    	  </test>
    </root>


    J'ai donc toujours mon programme, avec les modifications faites pour qu'il me repère toutes les balises <a> d'une balise <test>:

    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
    import re
    import sys
    import xml.etree.ElementTree as ET
     
    fichier= ("TestPrésence.xml")
    tree = ET.parse(fichier)
    root = tree.getroot()
     
     for test in root.findall(".//test"):
        for ssdata in test.iter('ssData'):
            cbalisea = ssdata.findall('a')
            if len(cbalisea)==0:
                print("mot", "NA")
                continue
            for balisea in cbalisea:
                for font in balisea.iter('Font'):
                    print ("mot:", font.text)

    Dans le même principe que pour tester la présence de la balise avec len() ==0, je souhaite écrire ceci, mais ça ne fonctionne pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Data = test.findall("Data")
    if len(Data) ==1:
    Du coup, je veux essayer de demander à mon programme de ne prendre la première balise <Data> en comptant le nombre de balises trouvées et en ne prenant que la première.
    Quelle méthode je peux utiliser?

  7. #7
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Dans ce cas, il y a au moins deux possibilités à consider : il peut de ne pas y avoir l'élément Data du tout, et si il y en a, il peut de ne pas y avoir un qui ait un attribut Type de valeur Number. Donc, c'est un peu plus compliqué et le xpath est là pour facilité la logique. ElementTree ne réclame pas la conformité avec w3c xpath 1.0, mais, il s'améliore au fur et à mesure. Pour ElementTree 1.3 (Python 2.7+), ce genre de xpath est supporté.
    Code python2.7+ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        cData=test.findall(".//Data[@Type='Number']")
        if len(cData)==0:
            print("data ", "NA")
        else:
            print("data ", cData[0].text)

Discussions similaires

  1. Réponses: 0
    Dernier message: 19/10/2015, 11h05
  2. Tester la présence de plusieurs mots dans une phrase
    Par Azerty32 dans le forum Général Python
    Réponses: 20
    Dernier message: 30/07/2010, 18h15
  3. Réponses: 10
    Dernier message: 15/03/2009, 15h52
  4. tester la présence de balises dans le fichier xml
    Par Balbuzard dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 29/08/2008, 16h11
  5. Tester l'existence d'un dossier dans plusieurs sous dossier
    Par titeZ dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 29/01/2008, 22h30

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