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

Langage PHP Discussion :

simpleXML - grouper et calculer directement lors de la lecture d'un XML [PHP 5.6]


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 126
    Points : 57
    Points
    57
    Par défaut simpleXML - grouper et calculer directement lors de la lecture d'un XML
    Bonjour.
    Je me noie dans un verre d'eau, je cherche à grouper et calculer à la lecture d'un fichier XML dans ce style :
    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
     
    SimpleXMLElement Object
    (
        [serieMesuresDateesListe] => SimpleXMLElement Object
            (
                [serieMesures] => Array
                    (
                        [0] => SimpleXMLElement Object
                            (
                                [Id] => 12345
                                [grandeur] => AA
                                [mesuresDateesListe] => SimpleXMLElement Object
                                    (
                                        [mesureDatee] => SimpleXMLElement Object
                                            (
                                                [dateFin] => 2020-09-14T01:01:12
                                                [valeur] => 10
                                            )
     
                                    )
     
                            )
     
                        [1] => SimpleXMLElement Object
                            (
                                [Id] => 12345
                                [grandeur] => AA
                                [mesuresDateesListe] => SimpleXMLElement Object
                                    (
                                        [mesureDatee] => SimpleXMLElement Object
                                            (
                                                [dateFin] => 2020-09-14T01:01:12
                                                [valeur] => 20
                                            )
     
                                    )
     
                            )
     
                        [2] => SimpleXMLElement Object
                            (
                                [Id] => 67890
                                [grandeur] => AA
                                [mesuresDateesListe] => SimpleXMLElement Object
                                    (
                                        [mesureDatee] => SimpleXMLElement Object
                                            (
                                                [dateFin] => 2020-09-14T01:01:12
                                                [valeur] => 30
                                            )
     
                                    )
     
                            )
     
                        [3] => SimpleXMLElement Object
                            (
                                [Id] => 67890
                                [grandeur] => AA
                                [mesuresDateesListe] => SimpleXMLElement Object
                                    (
                                        [mesureDatee] => SimpleXMLElement Object
                                            (
                                                [dateFin] => 2020-09-14T01:01:12
                                                [valeur] => 40
                                            )
     
                                    )
     
                            )
     
                    )
     
            )
     
    )
    Dans cet exemple, nous avons deux differents ID (12345 et 67890) et je voudrais additionner toutes les valeurs de chaque ID qui ont une GRANDEUR en AA, quel est le plus simple, rapide et efficace?
    obtenir donc :
    12345 = 30
    67890 = 70

    Merci !

  2. #2
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 255
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 255
    Points : 8 548
    Points
    8 548
    Billets dans le blog
    17
    Par défaut
    Quelque chose te gêne en particulier ?
    Donne-nous tes tentatives pour qu'on t'aide à compléter/corriger

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 126
    Points : 57
    Points
    57
    Par défaut
    Bonjour!
    En fait, j'attend plutot des conseils sur la meilleure logique pour aborder cela, pour l'instant j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    foreach($xml->serieMesuresDateesListe->serieMesures as $Liste) 
            {         
                if($Liste->grandeur == 'AA')
                { 
                }
             }
    mais pour additionner les valeurs ?!

  4. #4
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 255
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 255
    Points : 8 548
    Points
    8 548
    Billets dans le blog
    17
    Par défaut
    J'utiliserais un tableau associatif id => valeurs cumulées

    Ça donnerait :

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $valeurs = [];
    foreach ($xml->serieMesuresDateesListe->serieMesures as $Liste) {         
        if($Liste->grandeur == 'AA') {
            // $Liste->mesuresDateesListe peut-il être un tableau ? Si oui le parcourir
            $valeur = $Liste->mesuresDateesListe->mesureDatee->valeur;
            $id = $Liste->Id;
            if (!isset($valeurs[$id])) { // Si ID pas encore référencé...
                $valeurs[$id] = 0; // On l'initialise à 0
            }
            $valeurs[$id] += $valeur; // Valeurs cumulées pour chaque ID
        }
    }
     
    print_r($valeurs); // ['12345' => 30, '7890' => 70]

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 126
    Points : 57
    Points
    57
    Par défaut
    Bonsoir et merci!
    Cela ne fonctionne pas et affiche juste Array ( )
    Question de tableau?
    Déjà en mettant print_r($id); il affiche le nombre correct de lignes ID, et les valeurs pour chaque lignes sont bien récupéres via print_r($valeur).
    Mais il n'y a aucune valeur dans $valeurs[$id], ni avant ni aprés, il n'affiche même pas 0 aprés le isset de $valeurs[$id]), un var_dump affiche NULL! Il semble que la ligne suivante ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if (!isset($valeurs[$id])) { // Si ID pas encore référencé...
                    $valeurs[$id] = 0; // On l'initialise à 0           
                    }
    Merci !

  6. #6
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 255
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 255
    Points : 8 548
    Points
    8 548
    Billets dans le blog
    17
    Par défaut
    Il nous faudrait de quoi tester : XML et dernière version du script

  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
    On peut le faire en profitant pleinement le support (partiel) de xpath par simplexml: comme ça.
    Code php : 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
    //Supposons $xml est le document chargé par simplexml
    //D'abord on fait découvrir les Id uniques
    //où j'ajoute des mesures un peu avancées en gardant contre la possibilité d'avoir la présence des espaces vides insignifiants;
    //et puis, on fait la calcul encore via xpath.
     
    $idlist=$xml->xpath('/serieMesuresDateesListe/serieMesures/Id');
     
    if ($idlist) {
        foreach($idlist as &$id) {
            $id=trim($id);
        }
     
        $idunique=array_unique($idlist);    // les Id unques sans espace vide insignifiant
     
        foreach($idunique as $id) {
            $agregat=0;
            $vlist=$xml->xpath("/serieMesuresDateesListe/serieMesures[normalize-space(Id)=$id]/mesuresDateesListe/mesureDatee/valeur");
            foreach($vlist as $v) {
                $agregat+=(int)$v;
            }
     
            // montrer les résultats d'une façon ou d'une autre
            echo "id=$id; valeur=$agregat\n";
        }
    }
    Voilà !

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 126
    Points : 57
    Points
    57
    Par défaut
    YES merci tsuji, MAIS il faut retirer le slash en début d'adresse du xpath pour que cela fonctionne : ->xpath('serieMesuresDateesListe

    Néanmoins, on arrive à faire l'addition totale mais je souhaite l'addition uniquement pour les valeurs avec GRANDEUR en AA ! Après cela ce sera fantastique!
    Du genre qui ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $vlist=$xml->xpath("/serieMesuresDateesListe/serieMesures[normalize-space(Id)=$id]&&[normalize-space(grandeur)=AA]/mesuresDateesListe/mesureDatee/valeur");

  9. #9
    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
    Oui, si cette valeur de grandeur s'applique comme une donnée et fixe, on peut l'appliquer dans le xpath simplement ... (il faut connaître la technologie de xpath un peu plus approndie tout de même).
    Code php : 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
     
    $grandeur='AA';
    //etc...
    if ($idlist) {
        //etc etc...
        foreach($idunique as $id) {
            $agregat=0;
            $vlist=$xml->xpath("/serieMesuresDateesListe/serieMesures[normalize-space(Id)='$id' and grandeur='$grandeur']/mesuresDateesListe/mesureDatee/valeur");
            foreach($vlist as $v) {
                $agregat+=(int)$v;
            }
     
            // montrer les résultats d'une façon ou d'une autre
            echo "id=$id; grandeur=$grandeur; valeur=$agregat\n";
        }
    }
    J'ai ajouté une pair d'apostrophes autour de $id comme pour $grandeur - je pense c'est un peu meilleur : sans les apostrophes, comme j'ai écrit dans mon message précédant, je me base au fait que les $id soient tous numériques (12345, 67890). Avec les apostrophes, cet hypothèse n'est plus nécessaire, et c'est mieux.

    Et puis, on peut appliquer normalize-space() au balise grandeur aussi, il vaut mieux; je ne l'ai pas écrit explicitement ici pour que la ligne ne soit pas trop longue...

    MAIS il faut retirer le slash en debut d'adresse du xpath pour que cela fonctionne : ->xpath('serieMesuresDateesListe
    Je ne le pense pas : mais je ne sais pas ce que le xml concret sur lequel vous travaillez.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 126
    Points : 57
    Points
    57
    Par défaut
    Impeccable merci!!!! Ca fonctionne parfaitement !
    Je clique sur Resolu car sinon je vais encore me prendre un avertissement sans sommation ;-)

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

Discussions similaires

  1. Probleme lors d'une lecture de fichier XML VB2010
    Par nimbus629 dans le forum VB.NET
    Réponses: 6
    Dernier message: 17/06/2011, 12h51
  2. effectuer un calcul directement apres la saisie qur userform
    Par rimked dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 26/01/2008, 23h50
  3. [Calcul] Bug lors d'un calcul depuis une saisie TextBox.
    Par telodo dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 28/09/2007, 01h15
  4. Réponses: 1
    Dernier message: 29/06/2007, 14h58
  5. Réponses: 4
    Dernier message: 28/05/2006, 19h00

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