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

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

C# Discussion :

décoder des listes <ol> et <li> html


Sujet :

C#

  1. #1
    Membre régulier
    Femme Profil pro
    amateur curieux
    Inscrit en
    Janvier 2024
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : amateur curieux

    Informations forums :
    Inscription : Janvier 2024
    Messages : 7
    Par défaut décoder des listes <ol> et <li> html
    Bonjour,
    J'essaie en vain de traduire une string html en liste lisible (le boulot que fait un navigateur), mais je tourne en rond.

    Avec le package agility pack, node.ChildNodes a l'air de ne prendre que que le 1é niveau des Childnodes, ce qui fait que si une liste <ol> est imbriquée dans un des <li> des Childnodes, cette liste imbriquée disparait purement et simplement.

    Je passe un temps fou pour réinventer l'eau chaude.
    Et c'est bon ni pour le bilan carbone de la planète, ni pour ma santé mentale.

    Il n'y aurait pas un moyen, en rajoutant des balises d'entête html à cette string

    <ol><li>item1<ol type="a"><li>item a<ol type="i"><li>item i</li></ol></li><li>item b<ol type="i"><li>item i</li><li>item ii</li></ol></li></ol></li><li>item2</li></ol>

    et en utilisant un client C#, d'obtenir cette jolie string

    1. item1
    ....a. item a
    ........i. item i
    ....b. item b
    ........i. item i
    ........ii. item ii
    2. item2
    (avec des blancs à la place des ..., mais les blancs sont avalés à la publication sur le forum)
    string que je pourrai alors stocker dans un joli fichier ?

    Merci par avance pour vos conseils

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 540
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 540
    Par défaut
    c'est le rôle en partie d'un parser html.
    En faisant une petite recherche je suis tombé sur le package nugget Html Agility Pack https://html-agility-pack.net/download
    Sur leur site, on peut questionner ChatGPT, qui m'a fourni une réponse en lui posant ta problématique (mais je ne l'ai pas testé/vérifié)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    using HtmlAgilityPack;
    using System;
     
    class Program
    {
        static void Main()
        {
            var html = "<ol><li>item1<ol type=\"a\"><li>item a<ol type=\"i\"><li>item i</li></ol></li><li>item b<ol type=\"i\"><li>item i</li><li>item ii</li></ol></li></ol></li><li>item2</li></ol>";
            var doc = new HtmlDocument();
            doc.LoadHtml(html);
     
            PrintListItems(doc.DocumentNode.SelectNodes("//ol/li"), 0);
        }
     
        static void PrintListItems(HtmlNodeCollection nodes, int level)
        {
            if (nodes == null) return;
     
            foreach (var node in nodes)
            {
                Console.WriteLine($"{new string('.', level)}{node.InnerText.Trim()}");
     
                var childNodes = node.SelectNodes(".//ol/li");
                PrintListItems(childNodes, level + 1);
            }
        }
    }
    ça affiche directement le résultat dans la console, donc il faudra l'adapter un peu. https://zzzcode.ai/answer-question?i...a-f5eb21a5e4ec

    J'ai modifié la requête pour lui demander de le récupérer dans une variable String; voir le résultat (que je n'ai pas non plus testé) https://zzzcode.ai/answer-question?i...0-912c171b2736

    Il me propose aussi d'utiliser les expressions régulières pour éviter d'utiliser un package externe (code toujours pas testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    using System;
    using System.Text.RegularExpressions;
     
    class Program
    {
        static void Main(string[] args)
        {
            string html = "<ol><li>item1<ol type=\"a\"><li>item a<ol type=\"i\"><li>item i</li></ol></li><li>item b<ol type=\"i\"><li>item i</li><li>item ii</li></ol></li></ol></li><li>item2</li></ol>";
     
            string result = ConvertHtmlToList(html);
     
            Console.WriteLine(result);
        }
     
        static string ConvertHtmlToList(string html)
        {
            string pattern = @"<ol[^>]*>(.*?)<\/ol>";
            string result = Regex.Replace(html, pattern, match =>
            {
                string innerContent = match.Groups[1].Value;
                return ProcessList(innerContent, 1);
            }, RegexOptions.Singleline);
     
            return result;
        }
     
        static string ProcessList(string listContent, int depth)
        {
            string pattern = @"<li[^>]*>(.*?)<\/li>";
            string processedList = Regex.Replace(listContent, pattern, match =>
            {
                string listItem = match.Groups[1].Value.Trim();
                string indentation = new string('.', depth - 1);
                return $"{indentation}{depth}. {listItem}\n";
            }, RegexOptions.Singleline);
     
            return processedList;
        }
    }
    Edit: à la 1ère lecture, je n'avais pas vu que tu avais mentionné le package HtmlAgility d'où ma dernière proposition sans celui-ci

  3. #3
    Membre régulier
    Femme Profil pro
    amateur curieux
    Inscrit en
    Janvier 2024
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : amateur curieux

    Informations forums :
    Inscription : Janvier 2024
    Messages : 7
    Par défaut
    Citation Envoyé par umfred Voir le message
    c'est le rôle en partie d'un parser html.
    En faisant une petite recherche je suis tombé sur le package nugget Html Agility Pack https://html-agility-pack.net/download
    Sur leur site, on peut questionner ChatGPT, qui m'a fourni une réponse en lui posant ta problématique (mais je ne l'ai pas testé/vérifié)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    using HtmlAgilityPack;
    using System;
     
    class Program
    {
        static void Main()
        {
            var html = "<ol><li>item1<ol type=\"a\"><li>item a<ol type=\"i\"><li>item i</li></ol></li><li>item b<ol type=\"i\"><li>item i</li><li>item ii</li></ol></li></ol></li><li>item2</li></ol>";
            var doc = new HtmlDocument();
            doc.LoadHtml(html);
     
            PrintListItems(doc.DocumentNode.SelectNodes("//ol/li"), 0);
        }
     
        static void PrintListItems(HtmlNodeCollection nodes, int level)
        {
            if (nodes == null) return;
     
            foreach (var node in nodes)
            {
                Console.WriteLine($"{new string('.', level)}{node.InnerText.Trim()}");
     
                var childNodes = node.SelectNodes(".//ol/li");
                PrintListItems(childNodes, level + 1);
            }
        }
    }
    ça affiche directement le résultat dans la console, donc il faudra l'adapter un peu. https://zzzcode.ai/answer-question?i...a-f5eb21a5e4ec

    J'ai modifié la requête pour lui demander de le récupérer dans une variable String; voir le résultat (que je n'ai pas non plus testé) https://zzzcode.ai/answer-question?i...0-912c171b2736

    Il me propose aussi d'utiliser les expressions régulières pour éviter d'utiliser un package externe (code toujours pas testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    using System;
    using System.Text.RegularExpressions;
     
    class Program
    {
        static void Main(string[] args)
        {
            string html = "<ol><li>item1<ol type=\"a\"><li>item a<ol type=\"i\"><li>item i</li></ol></li><li>item b<ol type=\"i\"><li>item i</li><li>item ii</li></ol></li></ol></li><li>item2</li></ol>";
     
            string result = ConvertHtmlToList(html);
     
            Console.WriteLine(result);
        }
     
        static string ConvertHtmlToList(string html)
        {
            string pattern = @"<ol[^>]*>(.*?)<\/ol>";
            string result = Regex.Replace(html, pattern, match =>
            {
                string innerContent = match.Groups[1].Value;
                return ProcessList(innerContent, 1);
            }, RegexOptions.Singleline);
     
            return result;
        }
     
        static string ProcessList(string listContent, int depth)
        {
            string pattern = @"<li[^>]*>(.*?)<\/li>";
            string processedList = Regex.Replace(listContent, pattern, match =>
            {
                string listItem = match.Groups[1].Value.Trim();
                string indentation = new string('.', depth - 1);
                return $"{indentation}{depth}. {listItem}\n";
            }, RegexOptions.Singleline);
     
            return processedList;
        }
    }
    Edit: à la 1ère lecture, je n'avais pas vu que tu avais mentionné le package HtmlAgility d'où ma dernière proposition sans celui-ci

    Merci beaucoup pour ta réponse.
    J'ai résolu mon pb en faisant 2 fonctions : une qui appelle les Childnodes, filtre suivant que ce sont des <ol> ou des <li>, et une 2é, récursive, qui bosse avec les inner.html des noeuds étudiés avant.
    Je change les préfixes d'indexation (1,2 ... ou a, b ou i, ii .... suivant la profondeur de cette 2é fonction.
    Voilou

    Encore merci pour le tuyau de chatgpt, et ton code est beaucoup plus compact que le mien

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 540
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 540
    Par défaut
    Tout le mérite ici revient à ChatGPT (pour une fois qu'il semble sortir un truc correct )

  5. #5
    Membre régulier
    Femme Profil pro
    amateur curieux
    Inscrit en
    Janvier 2024
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : amateur curieux

    Informations forums :
    Inscription : Janvier 2024
    Messages : 7
    Par défaut
    chatgpt sort des trucs tellement corrects que la société mère limite son usage, depuis la baisse de chiffre qu'elle a pu mesurer depuis 18 mois.
    Et des outils comme Claude 3 et consorts feront de mieux en mieux, dans de plus en plus de domaines

    Sic mundia transit

  6. #6
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Un truc m'échappe.

    Depuis le 26 janvier 2000 le XHTML existe et aujourd'hui, le HTML tel qu'on l'a connu dans les années 90 n'est plus censé exister.

    Par conséquent, une page HTML est censée être du XML correctement formé (genre pas de balise <br> mais <br/> ou autre <option selected> remplacé par <option selected="true"> ou <option selected="selected">).

    Fort de ça, pourquoi ne pas utiliser un parseur XML, à commencer par celui fourni par .NET dans System.Xml ?

    Il me semble passablement plus simple à utiliser et probablement moins lourd qu'un Nuget complémentaire.

  7. #7
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    HTML 5 n'est pas "XML compliant". Par exemple, <br>, justement, est légal en HTML 5 (et même recommandé par certains linters), alors que XML exigerait une fermeture de la balise. Après, reste à voir si dans le contexte concerné il a est possible d'imposer du XHTML ou si ce sont des sources extérieures sur lesquelles il n'est pas possible d'avoir la main.

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

Discussions similaires

  1. Représentation intervallaire des listes arborescentes
    Par PMAR dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 05/11/2004, 09h35
  2. [servlet] gestion des listes d'erreurs ?
    Par MatMeuh dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 27/10/2004, 10h19
  3. [html:text][indexed]Valeurs des liste null...
    Par thibaut dans le forum Servlets/JSP
    Réponses: 13
    Dernier message: 08/09/2004, 09h36
  4. [glut] de l'intérêt des listes
    Par khayyam90 dans le forum OpenGL
    Réponses: 3
    Dernier message: 26/07/2004, 10h35
  5. [langage] probleme avec les listes dans des listes
    Par pqmoltonel dans le forum Langage
    Réponses: 7
    Dernier message: 27/04/2004, 12h32

Partager

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