1. Pour Black Friday on FRACASSE les prix ⚡ avec RM Tech Découverte
    Rejeter la notice

Problème de preg_match().

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par ortolojf, 15 Mai 2020.

  1. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Je met la dernière main à mon programme php, qui traduit automatiquement les scripts html en leur équivalent json.

    Je sèche sur une regex, censée sélectionner ce qui précède une balise correcte ( ouvrante ou fermante ), sachant que le contenu qui précède peut éventuellement contenir "<" et/ou ">".

    Les commentaires html ( classiques et Microsoft ) et les scripts sont filtrés et restitués séparément, et les balises <link et<meta faussement block sont corrigés inline.

    Le contenu json est produit, mais je bute sur un token imprévu.

    Par exemple, j'ai ce token : "%<=5</em>"

    Je dois sélectionner "%<=5" et puis "</em>".

    Quelle regex pourrait convenir ?

    Si je fais :

    PHP:

          
    if(preg_match("{^([^\<]+)(?:\<(?:\/)?[a-zA-Z0-9\.-]+)*(?:[ \t]+[^=]+=\"[^\"]+\")*}u"$tmp_data$output))

    Cà ne peut pas coller, puisque le contenu contient un "<".

    Si je fais :

    PHP:

          
    if(preg_match("{^(.+)(?:\<(?:\/)?[a-zA-Z0-9\.-]+)*(?:[ \t]+[^=]+=\"[^\"]+\")*}u"$tmp_data$output))

    Là il prend tout le token.

    Comment faire ?

    Merci beaucoup pour votre aide.

    Amicalement.
     
  2. emualliug
    emualliug WRInaute discret
    Inscrit:
    1 Février 2020
    Messages:
    237
    J'aime reçus:
    44
    Suis pas sûr de bien comprendre ce que tu souhaites faire, et ta regex me semble bien compliquée…

    De première part, les expressions rationelles sont absolument géniales, mais tout à fait inadaptées à un langage balisé comme le HTML. Vraiment. Mieux vaut utiliser d'autres outils bien plus adaptés.

    Toutefois, je te propose la regex suivante :
    Code:
    /<([a-z]+)>(.+)<\/\1>/
    
    TOUTEFOIS, telle quelle cette expression ne fonctionne que :
    • si les balises HTML sont composées uniquement de lettres minuscules ;
    • si la balise ne comprend pas d'attributs
    • composé d'un couple balise ouvrante / fermante (pas sur une balise auto-fermante)
    On peut bien sûr plus ou moins adapter la regex pour coller aux autres cas, mais on perd en concision.
     
  3. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Pardon

    Je dis bien : "ce qui précède une balise correcte".

    Merci beaucoup.

    Amicalement.
     
  4. emualliug
    emualliug WRInaute discret
    Inscrit:
    1 Février 2020
    Messages:
    237
    J'aime reçus:
    44
    Tu veux dire une expression avant une balise fermante, sans balise ouvrante avant ? exactement comme dans ton extrait du genre "%<=5</em>" ?

    Dans ce cas :
    Code:
    /(.*)(<\/[a-z]+>)/
    
     
  5. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Merci beaucoup.

    Voilà j'ai trouvé :

    PHP:

       $tmp_data 
    "%<5=</em>";



        if(
    preg_match("{((.)+)\<([\/]?[a-zA-Z]+)}"$tmp_data$output))
        {
            echo 
    "\t\tTrouvé.\n\n";
            
    print_r($output);
            echo 
    "\n\n";
        }
        else
        {
            echo 
    "\t\tPas trouvé.\n\n";
        }

    Celà donne :

    Trouvé.
    Array
    (
    [0] => %<5=</em
    [1] => %<5=
    [2] => =
    [3] => /em
    )

    J'ai le résultat dans $output[1].

    Cà marche.

    Je n'ai pas besoin d'autre chose que avant la balise.

    Merci beaucoup de ton aide.

    Amicalement.
     
  6. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Excusez-moi

    J'ai terminé de faire ce programme de traduction html -> json.

    Je l'ai testé pour l'instant sur deux fichier html.

    Il ne corrige pas le html défectueux.

    Je pourrais le rendre accessible en ftp sur mon serveur vps pour des tests.

    Ce petit programme est composé de deux scripts :

    parsing_html.php

    html_to_json.php

    Le premier script est inclus dans le second.

    Merci beaucoup de me dire si vous avez envie de le tester.

    Respectueusement.
     
  7. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Pardon

    Sur mon site, je peux mettre une page d'upload de vos fichiers html.

    Avec la classe CURLFile.

    Pour tester et afficher le json traduit.

    Mais.. Comment sécuriser les fichiers uploadés, pour ne pas me retrouver avec serveur hacké ?

    Merci beaucoup.

    Amicalement.
     
  8. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Pour uploader un fichier, j'ai commencé en localhost par utiliser un formulaire multipart/form-data en html classique.

    Est-ce que c'est possible en php avec Curl ?

    Sachant qu'il faut faire une requête en mode post, et comment arranger l'interface de piochage de fichier ?

    Merci beaucoup.
     
  9. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Voili voilou

    Je ne résiste pas à vous montrer mon interface d'upload de fichier.

    Dans le css il y a :

    Code:
    
    input[type="file"] {
        display: none;
    }
    
    
    Voici le html et php.

    Il n'y a pas l'affreux input en gris par défaut des navigateurs, car le input n'est pas affiché.

    Par contre, le nom du fichier choisi apparaît, grâce au javascript.


    PHP:

    <hr class="separation" />
    <br /><br />
    <form action="http://localhost/" method="post" enctype="multipart/form-data">
    <div>
    <div class="generic_main table1" itemscope itemtype="http://schema.org/Table">
    <div class="header-haut-group" itemprop="description">
    HTML => JSON</div>
    <div class="table-row">
    <label for="file-upload" class="upload_file">Choissez un fichier</label>
    <input type="file" name="file-upload" id="file-upload" />
    Fichier : <span id="file-upload-value">-</span>
    <!-- Fin de Row -->
    </div>
    <!-- Fin de generic_main table1 -->
    </div>
    <!-- Fin de div -->
    </div>
    <div>
    <p></p>
    <p></p>
    </div>
    <div class="generic_main table1" itemscope itemtype="http://schema.org/Table">
    <div class="footer-group">
    <input class="bouton_panneau" type="submit" name="submit" value="Submit" />
    </div>
    </div>
    </form>
    <script>

    function basename(str, sep) {
    return str.substr(str.lastIndexOf(sep) + 1);
    }

    document.getElementById('file-upload').onchange = function() {document.getElementById('file-upload-value').innerHTML=basename(this.value, '\\\\')};

    </script>
    <div>

    <?php

    if ($_POST['submit'])
    {
        
    $uploads_dir '/var/www/html/uploads';
        foreach(
    $_FILES['file-upload'] as $key => $value)
        {
            ${
    $key} = $value;
        }
        if (
    $error == UPLOAD_ERR_OK)
        {
            
    // basename() peut empêcher les attaques de système de fichiers;
            // la validation/assainissement supplémentaire du nom de fichier peut être approprié
            
    $name basename($name);
          
            if(
    move_uploaded_file($tmp_name"$uploads_dir/$name"))
            {
                echo 
    "<P>FILE UPLOADED TO: $name</P>";
            }
            else
            {
                echo 
    "<P>MOVE UPLOADED FILE FAILED!</P>";
              
                
    print_r(error_get_last());
            }
            if(
    $size == || $size 5242880)
            {
                exit(
    "keep the filesize under 50MB!!");
            }
            
    chmod (0777"$uploads_dir");
            
    chmod (0777"$uploads_dir/$name");
    //        unlink("$uploads_dir/$name");
        
    }
    }

    ?>

    <br />
    <br />
    </div>
    <hr class="separation" />

     
  10. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    J'aurais besoin d'une info.

    J'ai tout ce qu'il faut pour mettre une page d'upload de vos fichiers html, pour affichage ou download du json.

    J'ai testé en local sur mon ordi, çà roule.

    Mais... Comment sécuriser ces uploads pour ne pas attraper des hacks ?

    Je peux vérifier le mime_type.

    Merci beaucoup de votre aide.

    Amicalement.
     
  11. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Voici ma fonction sécurisée de réception des fichiers html que vous pourriez m'envoyer.

    Est-ce que celà vous paraît suffisamment sécurisé pour du réel ?

    Merci beaucoup de vos réponses.



    PHP:

    function receive_upload()
    {
        
    $dossier '/var/www/html/PWA/htm/';
        
    $fichier basename($_FILES['file-upload']['name']);
        
    $taille_maxi 5242880;
        
    $taille filesize($_FILES['file-upload']['tmp_name']);
        
    $extensions = array('.htm''.html');
        
    $extension strrchr($_FILES['file-upload']['name'], '.');
        
    $mime_types = array("text/plain""text/html");
        
    $error $_FILES['file-upload']['error'];

        if (
    $error != UPLOAD_ERR_OK)
        {
            
    $erreur 'Echec de l\'upload !';
        }
        
    //Début des vérifications de sécurité...
        
    elseif(!in_array($extension$extensions)) //Si l'extension n'est pas dans le tableau
        
    {
            
    $erreur 'Vous devez uploader un fichier de type html, htm, png, gif, jpg, jpeg, txt ou doc...';
        }
        elseif(
    $taille>$taille_maxi)
        {
            
    $erreur 'Le fichier est trop gros...';
        }
        elseif(!isset(
    $erreur)) //S'il n'y a pas d'erreur, on upload
        
    {
            
    //On formate le nom du fichier ici...
            
    $fichier strtr($fichier,
                
    'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ',
                
    'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy');
            
    $fichier preg_replace('/([^.a-z0-9]+)/i''-'$fichier);

            if(
    move_uploaded_file($_FILES['file-upload']['tmp_name'], $dossier $fichier)) //Si la fonction renvoie TRUE, c'est que ça a fonctionné...
            
    {
                
    $type mime_content_type($dossier $fichier);
                if(!
    in_array($type$mime_types))
                {
                    
    chmod($dossier $fichier0755);
                    
    unlink($dossier $fichier);

                    
    $erreur 'Vous devez uploader un fichier de type html, htm, png, gif, jpg, jpeg, txt ou doc...';
                    echo 
    $erreur;
                    echo 
    "<br /><br />\n";
                    return 
    false;
                }

                echo 
    'Upload effectué avec succès !';
               
                echo 
    "<br /><br />\n";
                echo 
    'Traduction du fichier HTML ' $fichier ' vers le fichier JSON ' pathinfo($fichierPATHINFO_FILENAME) . '.json';
                echo 
    "<br /><br />\n";
                
    $result start_traduction($dossier $fichier);
                if(
    $result === true)
                {
                    echo 
    'Traduction OK';
                    echo 
    "<br /><br />\n";
                    return 
    true;
                }
                else
                {
                    echo 
    'Traduction failed';
                    echo 
    "<br /><br />\n";
                    return 
    false;
                }
            }
            else 
    //Sinon (la fonction renvoie FALSE).
            
    {
                echo 
    'Echec de l\'upload !';
                echo 
    "<br /><br />\n";
                return 
    false;
            }
        }
        else 
    //Sinon (la fonction renvoie FALSE).
        
    {
            echo 
    $erreur;
            echo 
    "<br /><br />\n";
            return 
    false;
        }
    }

     
  12. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Rebonjour

    J'ai rajouté une vérification du type de fichier avec
    file.

    Celà vous semble-t-il suffisant sur le plan de la sécurité ?

    Merci beaucoup beaucoup de vos réponses.

    Respectueusement.



    PHP:

    function receive_upload()
    {
        
    $dossier '/var/www/html/PWA/htm/';
        
    $fichier basename($_FILES['file-upload']['name']);
        
    $taille_maxi 5242880;
        
    $taille filesize($_FILES['file-upload']['tmp_name']);
        
    $extensions = array('.htm''.html');
        
    $extension strrchr($_FILES['file-upload']['name'], '.');
        
    $mime_types = array("text/plain""text/html");
        
    $error $_FILES['file-upload']['error'];
        if (
    $error != UPLOAD_ERR_OK)
        {
            
    $erreur 'Echec de l\'upload !';
        }
        
    //Début des vérifications de sécurité...
        
    elseif(!in_array($extension$extensions)) //Si l'extension n'est pas dans le tableau
        
    {
            
    $erreur 'Vous devez uploader un fichier de type html, htm, png, gif, jpg, jpeg, txt ou doc...';
        }
        elseif(
    $taille>$taille_maxi)
        {
            
    $erreur 'Le fichier est trop gros...';
        }
        elseif(!isset(
    $erreur)) //S'il n'y a pas d'erreur, on upload
        
    {
            
    //On formate le nom du fichier ici...
            
    $fichier strtr($fichier,
                
    'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ',
                
    'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy');
            
    $fichier preg_replace('/([^.a-z0-9]+)/i''-'$fichier);
            if(
    move_uploaded_file($_FILES['file-upload']['tmp_name'], $dossier $fichier)) //Si la fonction renvoie TRUE, c'est que ça a fonctionné...
            
    {
                
    chmod($dossier $fichier0755);
                
    $type mime_content_type($dossier $fichier);
                if(!
    in_array($type$mime_types))
                {
                    
    unlink($dossier $fichier);
                    
    $erreur 'Vous devez uploader un fichier de type html, htm, png, gif, jpg, jpeg, txt ou doc...';
                    echo 
    $erreur;
                    echo 
    "<br /><br />\n";
                    return 
    false;
                }
                
    $result shell_exec("file " $dossier $fichier " 2>&1" );
                
    $result preg_replace("{^" str_replace("-""\-"$dossier $fichier) . "[: \t]*}"""$result);
                echo 
    $result;
                echo 
    "<br /><br />\n";
                
    /**
                * Voir autres
                * résultats
                * de file.
                **/
                
    $regex "^(HTML[ \t]+document)";
                if(!
    preg_match("{" $regex "}i"$result))
                {
                    
    unlink($dossier $fichier);
                    
    $erreur 'Vous devez uploader un fichier de type html, htm, png, gif, jpg, jpeg, txt ou doc...';
                    echo 
    $erreur;
                    echo 
    "<br /><br />\n";
                    return 
    false;
                }
                echo 
    'Upload effectué avec succès !';
               
                echo 
    "<br /><br />\n";
                echo 
    'Traduction du fichier HTML ' $fichier ' vers le fichier JSON ' pathinfo($fichierPATHINFO_FILENAME) . '.json';
                echo 
    "<br /><br />\n";
                
    $result start_traduction($dossier $fichier);
                if(
    $result === true)
                {
                    echo 
    'Traduction OK';
                    echo 
    "<br /><br />\n";
                    return 
    true;
                }
                else
                {
                    echo 
    'Traduction failed';
                    echo 
    "<br /><br />\n";
                    return 
    false;
                }
            }
            else 
    //Sinon (la fonction renvoie FALSE).
            
    {
                echo 
    'Echec de l\'upload !';
                echo 
    "<br /><br />\n";
                return 
    false;
            }
        }
        else 
    //Sinon (la fonction renvoie FALSE).
        
    {
            echo 
    $erreur;
            echo 
    "<br /><br />\n";
            return 
    false;
        }
    }

     
  13. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Voilà, je suis prêt à mettre sur mon site, les scripts php de test de mon traducteur html => json.

    Préférez-vous un téléchargement du json, ou un textarea ?

    Comment serait-il possible de tester en direct la validité syntaxique du fichier json ?

    Merci beaucoup si vous êtes intéressé pour tester mon traducteur.

    Amicalement.
     
  14. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Voilà c'est fait.

    Merci si vous voulez de tester :

    https://www.pronostics-courses.fr/PWA/from_html_to_json.php

    Les fichiers uploadés doivent être html, sinon ils sont effacés.

    Vous avez le json dans un textarea.

    Les directories htm/ et json/ sont dégraissés s'ils dépassent 128M.

    Les suppressions sont chronologiques.

    Chaque fichier doit avoir moins de 64M sinon effacé.

    A votre disposition.

    Amicalement.
     
  15. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Pardon

    Par rapport à ce traducteur : https://www.pronostics-courses.fr/PWA/from_html_to_json.php

    Souhaitez-vous que j'y adjoigne en amont un normalisateur de html type : tidy ?

    Vous pourriez avoir vos HTML corrigés dans une textarea et le JSON correspondant dans une autre textarea.

    Autre option : Téléchargement.

    Il va de soi qu'aucune utilisation n'est faite de vos téléchargements.

    Merci beaucoup de vos suggestions
     
  16. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 099
    J'aime reçus:
    303
    Je me demande vraiment quel est l'intérêt ?
     
  17. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour Monsieur spout

    Mon traducteur est en phase post alpha, il n'a pas encore été testé ( mode bêta puis release ).

    Ce matin, suite à essai de quelqu'un qui a essayé un petit script : dev-html.html ( sans DOCTYPE ), j'ai fait en sorte que les trois lignes à la fin du JSON produit, ne soient pas écrites quand le DOCTYPE n'est pas présent.

    Le json résultant est viable maintenant.

    L'utilité, c'est pour savoir si le soft fonctionne correctement, c'est-à-dire que le code json produit, est validé par les validateurs online courants.

    Je pense utiliser ce programme, quand je préparerai mon projet de PWA de mon site.

    Je serai obligé sur le serveur, de générer du json, et de l'afficher ( sur le smartphone ), comme html.

    Celà me facilitera grandement la tâche, de disposer en amont du json correspondant
    aux pages html de mon site, pour reprogrammer les scripts php, destinés à produire du json.

    Merci beaucoup de tester ;)

    Amicalement.
     
  18. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 099
    J'aime reçus:
    303
    Désolé mais je vois tjs pas l'intérêt pour un PWA ?
     
  19. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Docteur spout

    Pages de mon site en HTML=> JSON ( traducteur ).

    => Je dispose des pages en JSON, avec valeurs des variables au lieu des noms de variables.

    => Manuellement, je remplace les valeurs par les noms, tout en recopiant le code php de départ.

    => J'obtiens les scripts php d'origine, adaptés pour produire du json.

    J'ai bon ?

    Est-il possible de procéder plus rapidement ?

    Merci beaucoup de ton aide.
     
  20. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 099
    J'aime reçus:
    303
  21. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Précisément spout

    Je pense offrir des équivalents services web style REST, donc dont les données sont en JSON.

    C'est vrai que c'est un changement de paradigme par rapport au client-léger/serveur de mon site.

    Est-ce que tu pourrais me donner du grain à moudre/liens hypertextes sur des applications REST ?

    Pour éviter les requêtes incomplètes/trop massives, je compte spécialiser mes services web plutôt que de faire du GraphQL.

    A charge pour le client ( Javascript ), de formater les données.

    Merci beaucoup de ton aide.
     
  22. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Pardon Monsieur spout

    C'est vrai que la PWA sur le smartphone chargerait du JSON à distance ( services web du type REST ), et afficherait le HTML ad hoc.

    Ne penses-tu pas que le JSON est plus adapté pour le transport de data, que le HTML ?

    Pour ce qui est de la programmation de ces services web REST j'ai du pain sur la planche, mais si tu me donnais quelques infos sur la façon de structurer ce type d'architecture, je suppose que la moindre des choses, ce serait de la POO dur dur.

    Actuellement, le fichier HTML est arrangé avec Tidy, mais j'ai encore des bugs dans le traducteur.

    Merci beaucoup de ton aide.
     
  23. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour spout

    D'après : https://developers.google.com/web/ilt/pwa/live-data-in-the-service-worker

    La technique de cache et la méthode de migration site web -> PWA sont super mais j'ai besoin d'un petit détail :

    Si je comprend bien, je dois recevoir les data de ma bdd en mode serveur, mais quid de IndexedDB en local qui ne peut contenir que 50M maxi ?

    Donc, à la place de IndexedDB, que mettre en cache si mes data sont trop importantes ?

    Je dois :

    - Identifier les "assets fixes",
    - Identifier les data et requêtes SQL de mon site,
    - méthode mise en cache du fixe,
    - idem cache des data.
    - Le reste ( mise en forme ).

    Quelle politique de cache pour les contenus volumineux ?

    Merci beaucoup de vos réponses.

    Amicalement.
     
  24. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Voici ce que j'ai programmé à partir du script de la liste des courses :

    Code:
    
    {
        "root" : {
        "child" : [
        {
            "node" : "element",
            "tag" : "h1",
            "attr" : { "class" : "generic_en_tete en_tete" },
            "child" : [
            {
                "node" : "text",
                "text" : "Courses du lendemain Dimanche 24 Mai 2020"
            }
            ]
        },
        {
            "node" : "element",
            "tag" : "div",
            "attr" : { "class" : "tableau_liste" },
            "child" : [
            {
                "node" : "element",
                "tag" : "ul",
                "attr" : { "class" : "ligne_liste" },
                "child" : [
                {
                    "node" : "element",
                    "tag" : "li",
                    "attr" : { "class" : "cellule_liste_num_course" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "div",
                        "attr" : { "class" : "num_reunion_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "cellule_liste_libelle_reunion" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Réunion"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "cellule_liste_num_reunion" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "1"
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "li",
                    "attr" : { "class" : "cellule_liste_course" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "span",
                        "attr" : { "class" : "cellule_liste_nom_reunion" },
                        "child" : [
                        {
                            "node" : "text",
                            "text" : "DEAUVILLE"
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix du Musée Carnavalet"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "1"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ère"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,0.html", "title" : "Prix du Musée Carnavalet" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix du Musée Carnavalet"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Simple Couplés Ordre Trio Ordre"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "13h25"
                                },
                                {
                                    "node" : "text",
                                    "text" : "7"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix du Musée Rodin"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "2"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,1.html", "title" : "Prix du Musée Rodin" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix du Musée Rodin"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Simple Trio Couplés 2sur4 Multi"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "14h00"
                                },
                                {
                                    "node" : "text",
                                    "text" : "14"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix Ivanjica"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "3"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,2.html", "title" : "Prix Ivanjica" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix Ivanjica"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Trio Couplés 2sur4 Mini Multi Pick5"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "14h35"
                                },
                                {
                                    "node" : "text",
                                    "text" : "12"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix Madelia"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "4"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,3.html", "title" : "Prix Madelia" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix Madelia"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "2sur4 Multi Quinté+ Quarté Tiercé"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "15h15"
                                },
                                {
                                    "node" : "text",
                                    "text" : "14"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix Pont Cardinet"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "5"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,4.html", "title" : "Prix Pont Cardinet" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix Pont Cardinet"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Simple Trio Couplés 2sur4 Mini Multi"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "15h50"
                                },
                                {
                                    "node" : "text",
                                    "text" : "13"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix de Barbeville"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "6"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,5.html", "title" : "Prix de Barbeville" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix de Barbeville"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Simple Couplés Ordre Trio Ordre"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "16h25"
                                },
                                {
                                    "node" : "text",
                                    "text" : "5"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix de Solferino"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "7"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,6.html", "title" : "Prix de Solferino" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix de Solferino"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Simple Couplés Ordre Trio Ordre"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "17h00"
                                },
                                {
                                    "node" : "text",
                                    "text" : "7"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix de Chaville"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "8"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,7.html", "title" : "Prix de Chaville" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix de Chaville"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Simple Trio Couplés 2sur4 Mini Multi"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "17h35"
                                },
                                {
                                    "node" : "text",
                                    "text" : "12"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                },
                {
                    "node" : "element",
                    "tag" : "ul",
                    "attr" : { "class" : "ligne_liste" },
                    "child" : [
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_num_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_reunion_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Prix de Lormoy"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "div",
                            "attr" : { "class" : "num_course" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "9"
                            },
                            {
                                "node" : "element",
                                "tag" : "sup",
                                "child" : [
                                {
                                "node" : "text",
                                "text" : "ème"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    },
                    {
                        "node" : "element",
                        "tag" : "li",
                        "attr" : { "class" : "cellule_liste_course" },
                        "child" : [
                        {
                            "node" : "element",
                            "tag" : "url",
                            "attr" : { "url" : "http://localhost/php/courses_nouvelles/pronostics_new_courses,8.html", "title" : "Prix de Lormoy" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "span",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "Prix de Lormoy"
                                }
                                ]
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "span",
                            "attr" : { "class" : "pari" },
                            "child" : [
                            {
                                "node" : "text",
                                "text" : "Simple Couplés Ordre Trio Ordre"
                            }
                            ]
                        },
                        {
                            "node" : "element",
                            "tag" : "li",
                            "attr" : { "class" : "cellule_liste_partants" },
                            "child" : [
                            {
                                "node" : "element",
                                "tag" : "b",
                                "child" : [
                                {
                                    "node" : "text",
                                    "text" : "18h10"
                                },
                                {
                                    "node" : "text",
                                    "text" : "5"
                                }
                                ]
                            }
                            ]
                        }
                        ]
                    }
                    ]
                }
                ]
            }
            ]
        }
        ]
        }
    }
    
    
    Le problème, est de lire ce fichier en en extrayant les valeurs, de manière à produire du html.

    Dans ce fichier, j'ai des index numériques ( = non signifiants ) d'arrays et des index alphabétiques ( ex. attributs ).

    De manière générale, comment indexer du contenu json ?

    Merci beaucoup.

    Amicalement.
     
  25. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    J'ai mis au point les scripts produisant le JSON des pages : listes des courses ( anciennes et nouvelles ), et tableaux des statistiques.

    Je souhaiterais utiliser un Javascript Template Engine pour le rendu HTML, pour ne pas réinventer la roue, et économiser le développement.

    Pourriez-vous m'indiquer de bons JTE, pour mon projet de PWA ?

    Merci beaucoup de votre aide.

    Amicalement.
     
  26. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    J'ai été regarder du côté de Embedded Javascript Templates ( EJS ).

    Cà paraît lourd pour traduire ma syntaxe JSON en HTML.

    J'envisage ( en Javascript ), de faire un petit JTE dédié perso.

    Je suppose une fonction produisant le html avec le json en paramètre.

    De votre côté, avez-vous déjà implémenté celà ?

    Merci beaucoup.
     
  27. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Mon problème : parcourir l'arbre JSON en preorder et afficher les tag et classes ouvrantes, nestées avec les tags fermants.

    J'arrive très bien à afficher les balises avec classes.

    Mais je ne sais pas à quel moment lire les tags fermants.

    Dans la version récursive ci-dessous, la fonction func_out() se déclenche juste après la ligne où func_in() d'est déclenchée.

    Je ne sais pas nester les tags ( balises ).

    Voici les fonctions ( non récursives et récursives ) :

    Code:
    
    /**
     * NON RECURSIVE.
     **/
    /**
    function traverse(o, func) {
        const stack = [o]
        while (stack.length) {
        const obj = stack.shift()
        Object.keys(obj).forEach((key) => {
            func(key, obj[key], obj)
            if (obj[key] instanceof Object) {
            stack.unshift(obj[key])
            return
            }
        })
        }
    }
     **/
    /**
     * RECURSIVE.
     **/
    function traverse(obj, func_in, func_out)
    {
        if(obj !== null)
        {
            if (obj instanceof Array)
            {
                Object.keys(obj).forEach((key) => {
                    func_in(key, obj[key], obj);
                    traverse(obj[key], func_in, func_out);
                    func_out(key, obj[key], obj);
                });
            }
            else if (obj instanceof Object)
            {
                Object.keys(obj).forEach((key) => {
                    func_in(key, obj[key], obj);
                    traverse(obj[key], func_in, func_out);
                    func_out(key, obj[key], obj);
                });
            }
            return;
        }
    }
    
    
    Comment fermer les structures ouvertes par les tags ouvrants ?

    C'est un problème classique de récursivité.

    Merci beaucoup.

    Amicalement.
     
  28. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 099
    J'aime reçus:
    303
    Donc tu transformes du HTML en JSON pour ensuite re-transformer en HTML.
    T'as vraiment de la bonne toi :D

    La plupart des gens font: API REST JSON ou GraphQL => JS + HTML (Vue.js, React, Angular, ...)
     
  29. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Pardon spout

    J'ai trouvé une autre fonction ( non récursive ) :

    Code:
    
    traverse(obj, func)
    {
        var stack = new Array();
        var t = null;
    
        stack.unshift(obj);
        while(stack.length > 0)
        {
            t = stack.shift();
            if(t !== null)
            {
                func(t);
                if((t instanceof Object)||
                    (t instanceof Array))
                {
                    Object.keys(t).forEach((key) => {
                        stack.unshift(t[key]);
                    });
                }
            }
        }
    }
    
    

    Cette fonction figure dans "Algorithms in C" de Robert Sedgewich.

    L'erreur semble être que je déclenchais func_in dans le forEach à chaque itération.

    Merci spout de ton aide précieuse !

    Amicalement.
     
  30. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Pardon spout

    Que je t'explique.

    Le JSON dans mon cas, n'est pas du tout généré à la volée.

    Comme je le disais dans ce même thread, j'ai déjà traduit à la main la liste des courses ( anciennes et nouvelles ), et les tableau des pronostics.

    Celà veut dire, que ces éléments JSON sont maintenant produits dynamiquement, en lieu et place du HTML.

    Mon format JSON est ultra simple à traduire en HTML de manière
    automatique.

    Je suis en train de programmer ce traducteur JSON => HTML avec une fonction, théoriquement récursive, mais je ne sais pas clôturer les balises nestées, parce que je ne sais pas où se situe le code dans la fonction, qui correspond à des sorties de structures de pile.

    Quant à l'API REST JSON, ce sont des services web, précisément ces scripts PHP ci-dessus, qui produisent du JSON.

    Amicalement.
     
  31. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    J'ai trouvé le graal du parcours de JSON :

    Code:
    
    function traverse(o, callback_in, callback_out) {
            Object.keys(o).forEach((key) => {
                    var value = o[key];
                    if ((value !== null) &&
                            (value !== undefined) &&
                            (value instanceof Object)) {
                            callback_in.call(this, key, value);
                            traverse(value, callback_in, callback_out);
                            callback_out.call(this, key, value);
                    } else {
                            callback_in.call(this, key, value);
                    }
            });
    }
    
    
    Le callback_in() c'est pour entrer dans la structure, le callback_out() pour en sortir.

    Le callback_out(), me permet de générer les balises fermantes.

    Dans callback_in(), je fais : array_tag.unshift(tag) pour chaque tag ( = balise ) rencontré.

    Dans callback_out() je lis array_tag : tag = array_tag.shift() et je génère la balise html fermante.

    Vous pouvez vous servir de cette fonction récursive.

    Cà marche avec des objets JSON parsés avec JSON.parse().

    Amicalement.
     
  32. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Rebonjour

    Je suis newbie avec fetch et tout çà.

    Est-ce que çà marche ?

    Je compte utiliser cet event fetch dans la PWA.


    Code:
    
    self.addEventListener('fetch', function(evt) {
        evt.respondWith(
            caches.open(CACHE).then(function(cache) {
                var requestURL = new URL(evt.request.url);
                var arrayURL = requestURL.pathname.split('.');
                var suffix = arrayURL[arrayURL.length - 1];
                if(suffix === 'css') {
                    return cache.match(evt.request).then(function (response) {
                        return response || fetch(evt.request).then(function(response) {
                            cache.put(evt.request, response.clone());
                            return response;
                        });
                    });
                } else {
                    return cache.match(evt.request).then(function (response) {
                        return response.json() || fetch(evt.request).then(function(response) {
                            cache.put(evt.request, response.clone());
                            return response.json();
                        });
                    });
                }
            })
        )
    });
    
    
     
  33. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Excusez-moi

    Je compte suivre les instructions de Google, en alimentant des templates html à chaque chargement d'url, et j'ai déjà configuré ( entre autre ), les events fetch en mode StaleOr Revalidate pour les data, et cache le html.

    Ceci pour optimiser les données circulant sur le réseau.

    Ma question : Comment alimenter du contenu dynamique en boucles, vers des templates fixes ?

    Merci beaucoup.

    Amicalement.
     
  34. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Comment gérez-vous le problème de contenu variable dans une PWA ?

    1- Contenus direct html chargés sur le serveur ou le cache ?

    2- Contenus json ( idem ) donc plus réduits translatés par le client en html ?

    3- Template ( ex. Mustache ), et dans ce cas, comment gérer les contenus variables ?

    Merci beaucoup de votre aide.

    Respectueusement.
     
  35. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bon.

    Mustache semble permettre les boucles :

    Code:
    
    var drugs = [];
    for (var i = 0, drug; (drug = data[I]); ++i) {
        drugs.push(drug);
    }
    var template = "{{#drugs}}<p>{{Drug}}</p>{{/drugs}}";
    var html = Mustache.to_html(template, {drugs: drugs});
    document.getElementById("cnt").appendChild(html);
    
    
    Je recherche l'optimisation réseau, donc Mustache semble adéquat pour injecter les data dans le html provenant du cache.

    Je vais adapter mes scripts json.

    Merci beaucoup de votre aide.

    Amicalement.
     
  36. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Finalement,

    J'ai déjà de bons résultats en local avec mon traducteur json => html.

    Je vais simplement produire du json et le mettre en html.

    Le seul bug pour l'instant, est que le html est une simple chaîne de caractères,
    et non pas un arbre dom.

    Je peux faire avec innerHTML, mais ce n'est pas viable.

    Je vais probablement changer ma fonction genere_html(json_obj) en générant du dom plutôt qu'une chaîne de caractères.

    Pour l'instant, cette fonction tout azimut translate très bien mon format json propriétaire en html, pour quatre types de pages :

    - Liste des courses ( lendemain/aujourd'hui ou passées ),
    - Tableau des statistiques ( idem ).

    Après, je mettrai en place progressivement le contenu.

    Bien à vous.

    Amicalement.
     
  37. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour


    Voici le code de ma fonction genere_dom(json_object, table_id), qui fait appel à la fonction récursive traversal() , et essaye de construire le DOM à partir de mon objet JSON, lui-même produit par mes scripts PHP.

    Les fonctions level() et chaine() ne sont plus utilisées, elles datent de la version précédente ( genere_html() ), qui marche mais m'oblige à rabouter l'arbre html avec innerHTML au lieu de appendChild().

    Je suis très mauvais en récursivité et en copie de portions de DOM, je n'obtiens rien à la fin, mais genere_dom() s'exécute correctement, sans propager le DOM jusqu'à la racine.

    Cependant, le innerHTML qui devrait être signalé par le : "console.log('father_text = ' + father.parentNode().toString());" n'est jamais exécuté.

    Je peux générer et donner le contenu dans array_html2[] si besoin.

    La syntaxe du json_object est vérifiée correcte sans warning/erreur.

    Le array_html[] quant à lui, donne le html.

    Merci beaucoup de votre aide.

    Amicalement.



    Code:
    
    function chaine(str)
    {
        return '"' + str + '"';
    }
    function level(len)
    {
        var str = "";
        for(i = 0; i < len; i++)
        {
            str += "\t";
        }
        return(str);
    }
    function value_father(father)
    {
        var tmp_father;
        if(father === null)
        {
            tmp_father = father;
        }
        else
        {
            tmp_father = father.cloneNode(true);
        }
        return tmp_father;
    }
    function traverse(o, callback_in, callback_out, father) {
        Object.keys(o).forEach((key) => {
            var value = o[key];
            if ((value !== null) &&
                (value !== undefined) &&
                (value instanceof Object)) {
                father = callback_in.call(this, key, value, value_father(father));
                father = traverse(value, callback_in, callback_out, value_father(father));
                father = callback_out.call(this, key, value, value_father(father));
            } else {
                father = callback_in.call(this, key, value, value_father(father));
            }
        });
        return value_father(father);
    }
    var array_html    = new Array();
    var array_html2    = new Array();
    var tag_array    = new Array();
    var root_dom    = null;
    var enfant    = null;
    var id_table    = null;
    var i_html    = -1;
    var i_html2    = -1;
    var len        = 0;
    var attr    = null;
    var tag        = null;
    var attr    = null;
    var is_child    = null;
    function visit_in(key, obj, father)
    {
        /**
        i_html2++;
        array_html2[i_html2] = 'obj_in[ ' + key + ' ] = ' + obj + "\n";
        return;
        **/
        var regex = new RegExp('^[0-9]+$', 'g');
        if((key === undefined)||
            (key === null)||
            (regex.test(key)))
        {
            return value_father(father);
        }
        switch (key) {
            case "root" :
                tag = key;
                len = 0;
                is_child = false;
                break;
            case "node" :
                tag = key;
                is_child = false;
                break;
            case "tag" :
                tag = key;
                i_html++;
                array_html[i_html] = level(len) + '<' + obj;
                tag_array.unshift(obj);
                if((father !== null)&&
                    (father !== undefined))
                {
                    enfant = document.createElement(obj);
                    father.appendChild(enfant);
                    console.log('father_next = ' + value_father(father).toString());
                    return value_father(enfant);
                }
                else
                {
                    alert('Erreur father null : ' + value_father(father));
                    return null;
                }
                is_child = false;
                break;
            case "attr" :
                tag = key;
                is_child = false;
                break;
            case "child" :
                if(tag === 'tag')
                {
                    array_html[i_html] += '>' + "\n";
                }
                tag = key;
                len++;
                is_child = true;
                break;
            case "text" :
                tag = key;
                i_html++;
                array_html[i_html] = level(len) + obj + "\n";
                if((father !== null)&&
                    (father !== undefined))
                {
                    if(typeof father.parentNode === 'function')
                    {
                        father.parentNode().innerHTML = obj;
                        console.log('father_text = ' + father.parentNode().toString());
                    }
                }
                is_child = false;
                break;
            default :
                if(tag === 'attr')
                {
                    array_html[i_html] += ' ' + key + '=' + chaine(obj);
                    attr = document.createAttribute(key);
                    attr.value = obj;
                    if((father !== null)&&
                        (father !== undefined))
                    {
                        father.attributes.setNamedItem(attr);
                        console.log('father_attr = ' + value_father(father).toString());
                    }
                }
                break;
        }
        return value_father(father);
    }
    function visit_out(key, obj, father)
    {
        var tag_out = null;
        /**
        i_html2++;
        array_html2[i_html2] = 'obj_out[ ' + key + ' ] = ' + obj + "\n";
        return;
        **/
        var regex = new RegExp('^[0-9]+$', 'g');
        if((key === undefined)||
            (key === null)||
            (regex.test(key)))
        {
            return value_father(father);
        }
        switch (key) {
            case "child" :
                tag_out = tag_array.shift();
                if(tag_out !== 'root')
                {
                    len--;
                    i_html++;
                    array_html[i_html] = level(len) + '</' + tag_out + '>' + "\n";
                    /**
                    if((enfant !== null)&&
                        (enfant !== undefined))
                    {
                        if(enfant.parentNode instanceof Function)
                        {
                            father = enfant.parentNode().cloneNode(true);
                        }
                    }
                    **/
                }
                break;
            case "attr" :
                array_html[i_html] += '>' + "\n";
                break;
            default :
                break;
        }
        return value_father(father);
    }
    function genere_html(json_object, table_id) {
        root_dom = document.createElement('div');
        traverse(json_object, visit_in, visit_out, root_dom);
        /**
        var str = '';
        for(var i = 0; i <= i_html; i++) {
            str += array_html[i];
        }
        **/
        return  root_dom.cloneNode(true);
        //    return str;
    }
    
    
     
  38. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Pardon

    Cà marche maintenant.

    Le elem[0] a bien le html.

    Le id_table est un div dans le html au départ.


    Voici le code :

    Code:
    
    function chaine(str)
    {
        return '"' + str + '"';
    }
    function level(len)
    {
        var str = "";
        for(i = 0; i < len; i++)
        {
            str += "\t";
        }
        return(str);
    }
    /**
     * Tree traversal.
     **/
    function traverse(o, callback_in, callback_out) {
        Object.keys(o).forEach((key) => {
            var value = o[key];
            if ((value !== null) &&
                (value !== undefined) &&
                (value instanceof Object)) {
                callback_in.call(this, key, value);
                traverse(value, callback_in, callback_out);
                callback_out.call(this, key, value);
            } else {
                callback_in.call(this, key, value);
            }
        });
    }
    var array_html    = new Array();
    var array_html2    = new Array();
    var elem    = new Array();
    var tag_array    = new Array();
    var id_table    = null;
    var i_html    = -1;
    var i_html2    = -1;
    var len        = null;
    var len2    = null;
    var attr    = null;
    var tag        = null;
    var attr    = null;
    var is_child    = null;
    function visit_in(key, obj)
    {
        /**
        i_html2++;
        array_html2[i_html2] = 'obj_in[ ' + key + ' ] = ' + obj + "\n";
        return;
        **/
        var regex = new RegExp('^[0-9]+$', 'g');
        if((key === undefined)||
            (key === null)||
            (regex.test(key)))
        {
            return;
        }
        switch (key) {
            case "root" :
                tag = key;
                len = 0;
                len2 = 0;
                elem[len2] = document.getElementById(id_table);
                is_child = false;
                break;
            case "node" :
                tag = key;
                is_child = false;
                break;
            case "tag" :
                tag = key;
                i_html++;
                array_html[i_html] = level(len) + '<' + obj;
                tag_array.unshift(obj);
                elem[len2] = document.createElement(obj);
                elem[len2 - 1].appendChild(elem[len2]);
                console.log('elem[ ' + len2 - 1 + ' ] = ' + elem[len2 - 1]);
                console.log('elem[ ' + len2 + ' ] = ' + elem[len2]);
                is_child = false;
                break;
            case "attr" :
                tag = key;
                is_child = false;
                break;
            case "child" :
                if(tag === 'tag')
                {
                    array_html[i_html] += '>' + "\n";
                }
                tag = key;
                len++;
                len2++;
                is_child = true;
                break;
            case "text" :
                tag = key;
                i_html++;
                array_html[i_html] = level(len) + obj + "\n";
                elem[len2 - 1].innerHTML = obj;
                console.log('elem[ ' + len2 - 1 + ' ] = ' + elem[len2 - 1]);
                is_child = false;
                break;
            default :
                if(tag === 'attr')
                {
                    array_html[i_html] += ' ' + key + '=' + chaine(obj);
                    attr = document.createAttribute(key);
                    attr.value = obj;
                    elem[len2].attributes.setNamedItem(attr);
                    console.log('elem[ ' + len2 + ' ] = ' + elem[len2]);
                }
                break;
        }
    }
    function visit_out(key, obj)
    {
        var tag_out = null;
        /**
        i_html2++;
        array_html2[i_html2] = 'obj_out[ ' + key + ' ] = ' + obj + "\n";
        return;
        **/
        var regex = new RegExp('^[0-9]+$', 'g');
        if((key === undefined)||
            (key === null)||
            (regex.test(key)))
        {
            return;
        }
        switch (key) {
            case "child" :
                tag_out = tag_array.shift();
                if(tag_out !== 'root')
                {
                    len--;
                    i_html++;
                    array_html[i_html] = level(len) + '</' + tag_out + '>' + "\n";
                }
                len2--;
                break;
            case "attr" :
                array_html[i_html] += '>' + "\n";
                break;
            default :
                break;
        }
    }
    function genere_html(json_object, table_id) {
        id_table = table_id;
        traverse(json_object, visit_in, visit_out);
        /**
        var str = '';
        for(var i = 0; i <= i_html2; i++) {
            str += array_html2[i];
        }
        **/
        return elem[0];
        return str;
    }
    
    
     
  39. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Merci beaucoup à Monsieur Olivier Duffez et tous les intervenants sur ce forum, sans qui mon site ne serait pas ce qu'il est.

    La fonction ci-dessus fonctionne parfaitement bien, j'ai testé en local sur deux scripts php ( listes des courses ) rendant du json, le hml est impec et le rendu à l'écran est parfait.

    Demain, je testerai avec les deux autres scripts ( tableau de statistiques ), qui rendent du json correct.

    La technique( PWA ) consistant à downloader du json et le traduire en html côté client me semble quand même assez viable, nonobstant le conseils de Spout qui préfère du html pur.

    Je cherche à améliorer la qualité syntaxique de mon html, en portant l'attention en amont sur la rectitude du json.

    Merci de me donner vos avis à ce sujet.

    Respectueusement.
     
  40. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bah...

    Je ne résiste pas.

    Je vais charger des data et puis alimenter deux contenus avec ( par page ), au lieu de charger du contenu directement.

    Celà m'économisera du réseau ( 1 requête http au lieu de 2 ).

    Les tableaux de stats, quant à eux, resteront chargés tels quels.

    Voici les data :

    Code:
    
    [{"FIRST_PERIODE":"0", "LAST_PERIODE":"0", "nbr_max_couru":"", "JOUR":"03", "MOIS":"01", "AN":"2019", "course_exists":"", "file_non_partants":"/var/www/html/pwa/old/orig/non_partants169641-030119.txt", "hippodrome":"VINCENNES", "reunion":"1", "course":"1", "Actuel_nomCourse":"Prix Hersilie", "Actuel_nomTerrain":"Reunion:1:COURSE:1:SIMPLE::2:SUR:4:MULTI:QUINTE+", "nQ1":"13"},[{"max_Suppr":"15", "nJoursPreCourse":"26", "Actuel_partant":"6", "res_partant":"9", "Actuel_rang":""},{"max_Suppr":"10", "nJoursPreCourse":"9", "Actuel_partant":"8", "res_partant":"3", "Actuel_rang":"4"},{"max_Suppr":"27", "nJoursPreCourse":"33", "Actuel_partant":"7", "res_partant":"7", "Actuel_rang":"10"},{"max_Suppr":"45", "nJoursPreCourse":"12", "Actuel_partant":"1", "res_partant":"1", "Actuel_rang":"1"},{"max_Suppr":"39", "nJoursPreCourse":"26", "Actuel_partant":"4", "res_partant":"2", "Actuel_rang":"11"},{"max_Suppr":"11", "nJoursPreCourse":"9", "Actuel_partant":"9", "res_partant":"13", "Actuel_rang":"5"},{"max_Suppr":"13", "nJoursPreCourse":"19", "Actuel_partant":"3", "res_partant":"5", "Actuel_rang":"3"},{"max_Suppr":"33", "nJoursPreCourse":"9", "Actuel_partant":"2", "res_partant":"6", "Actuel_rang":"2"},{"max_Suppr":"18", "nJoursPreCourse":"22", "Actuel_partant":"5", "res_partant":"8", "Actuel_rang":"8"},{"max_Suppr":"3", "nJoursPreCourse":"6", "Actuel_partant":"13", "res_partant":"12", "Actuel_rang":"6"},{"max_Suppr":"19", "nJoursPreCourse":"5", "Actuel_partant":"11", "res_partant":"4", "Actuel_rang":"7"},{"max_Suppr":"3", "nJoursPreCourse":"6", "Actuel_partant":"14", "res_partant":"14", "Actuel_rang":"9"},{"max_Suppr":"3", "nJoursPreCourse":"9", "Actuel_partant":"12", "res_partant":"11", "Actuel_rang":""}]]0
    
    
     
  41. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Bonjour

    Je teste ( et donne à tester ), un script Javascript qui calcule automatiquement :

    La date locale du navigateur,
    la date UTC,
    et la date de mon serveur VPS ( méridien de Strasbourg ), avec le DST été/hiver.

    Ceci quel que soit ( théoriquement ), le navigateur client.

    Voici ce que j'obtiens à Paris, avec mon Chrome version : 83.0.4103.116 sous Linux Fedora 32 :

    Code:
    
    VPS_Date Offset = +02:00 => Heure d'été.
    VPS_Date Offset = +01:00 => Heure d'hiver.
     
    => VPS_Date = 2020-06-30T21:28:12+02:00
    
    Date de mon serveur VPS = Tue Jun 30 2020 21:28:12 GMT+0200 (heure d’été d’Europe centrale)
    
    Date Locale = 2020-6-30T21:28:12+02:00
    
    Date UTC = 2020-6-30T19:28:12+00:00
    
    
    L'url est :

    https://www.pronostics-courses.fr

    Les intitulés sont dans la console Javascript.

    Ce serait super sympa si vous pouviez tester et me dire si l'offset et la date sont corrects sur vos browsers.

    Respectueusement.
     
  42. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 177
    J'aime reçus:
    19
    Je vous demande pardon.

    Voici le contenu de la console Javascript :

    Je cherche simplement à savoir si l'heure du serveur VPS est correcte ( UTC+2 en été, UTC+1 en hiver ), et s'il n'y a pas d'erreur de calcul.

    Je peux donner les fonctions pour les dates UTC et locales sous forme de chaînes de caractères.

    Quant à l'heure du VPS, je calcule l'heure UTC plus le décalage du méridien 'Europe/Paris'.

    Je n'ose pas redonner l'url de la page d'accueil de mon site.

    Respectueusement.


    Code:
    
    ****************************************
    Date UTC = 2020-7-3T8:13:0+00:00
    ****************************************
    Date Locale = 2020-7-3T10:13:0+02:00
    ****************************************
    VPS_Date Offset = +02:00 => Heure d'été.
    VPS_Date Offset = +01:00 => Heure d'hiver.
    ****************************************
    Merci de signaler les erreur d'heure ou d'offset.
    ****************************************
    Serveur VPS = 2020-07-03T10:13:00+02:00
    ****************************************
    
    
     
Chargement...
Similar Threads - Problème preg_match() Forum Date
Probleme redirection d'un sous domaine deja redirigé URL Rewriting et .htaccess Hier à 20:23
Problème d’analyse de mon site web sur bing webmaster Référencement Bing Hier à 13:06
Problème calcul d'offset UTC par getTransitions ou DateTime. Développement d'un site Web ou d'une appli mobile Samedi à 12:50
Probleme indexation site web Crawl et indexation Google, sitemaps 16 Novembre 2020
Problème d'indexation Google (pages non indexées) Crawl et indexation Google, sitemaps 7 Novembre 2020
Search Console Problème d'indexation sur la search console Problèmes de référencement spécifiques à vos sites 3 Novembre 2020
Analytics et GTM : problème TAG Google Analytics 2 Novembre 2020
Problème page destination groupe d'annonces Google Ads AdWords 26 Octobre 2020
Problème de trafic incorrect (plus de 3000€) / RPM à 35€ AdSense 23 Octobre 2020
Problèmes d'indexations de Google Crawl et indexation Google, sitemaps 19 Octobre 2020