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

  1. #1
    Membre confirmé
    problème parcours fichier avec SAX: contenu balise dédoublé
    Bonjour à tous,

    je parcoure avec SAX (en utilisant le langage PHP) un fichier xml avec des mots dans une langue rare, et lorsque certains caractères/groupes de caractère sont rencontrés, le contenu de la balise est divisé en deux: tout se passe comme si on avait deux balises, l'une contenant la première lettre du mot et l'autre le reste. Ce problème parle-t-il à quelqu'un?

    Merci

  2. #2
    Modérateur

    Hello,

    je doute que tout se passe comme cela, en réalité. Quels sont les noms de ces différentes balises, dans ce cas ? Bref, peux-tu nous montrer concrètement ce qui te fait dire ça ?

    Pour information, en SAX, la réception du contenu texte d'une balise se fait en plusieurs fois. Quand ça se fait en une fois, ce n'est qu'un hasard amusant.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé
    Bonjour,

    concrètement, j'ai une balise qui a la tronche:

    Code XML :Sélectionner tout -Visualiser dans une fenêtre à part
    <tu att="xx">bána</tu>


    Et lors du parcours avec SAX:

    - le $tagName dans la fonction startElement est bien TU

    - (c'est cela le problème: ) dans la fonction qui récupère le contenu, la variable $tagContent est successivement égale à "b" puis à "ána". Le contenu est divisé en deux, ce qui m'empêche de faire directement une comparaison de chaîne de caractères avec le contenu de la balise

    - le $tagName dans la fonction endElement est bien TU

    cordialement

  4. #4
    Modérateur

    "La variable $tagContent" ?? Du code, s'il te plaît.

    Cela dit, ça ressemble exactement à ce que j'ai déjà dit juste au-dessus.

    Tu sembles considérer que dans le cas du XML que tu montres, le callback de character_data_handler sera appelé une seule fois, avec le contenu "bána".

    Ce n'est pas comme ça que fonctionne SAX. A la rigueur, peut-être que le callback ne sera appelé qu'une fois avec tout le contenu, ce n'est pas interdit.
    Mais il n'y a pas de raison que ce soit le cas.
    Tu dois t'attendre à ce que le contenu de la balise soit donné en plusieurs fois, bout à bout.
    En l'occurrence, "b" suivi de "ána" est parfaitement valide, puisque bout à bout ça fait "bána", le contenu exact de la balise.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé
    Citation Envoyé par thelvin
    "La variable $tagContent" ?? Du code, s'il te plaît.
    C'est la variable qui est censée contenir le contenu de la balise dans la fonction donnée en entrée de xml_set_character_data_handler. Elle est appelée comme cela dans tous les tutoriels que j'ai regardés, c'est pour cela que je pensais que cela serait parlant:

    Code PHP :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    xml_set_character_data_handler($parserXML, $FONCTION);
     
    public function FONCTION($parser, $tagContent){


    Citation Envoyé par thelvin
    Tu dois t'attendre à ce que le contenu de la balise soit donné en plusieurs fois, bout à bout.
    Ok. Etant donné que l'objectif de SAX est, sauf erreur de ma part, de récupérer le contenu de balises Xml, ce n'est pas terrible, non? Qu'utilise-t-on en général pour remettre les choses bout à bout?

  6. #6
    Modérateur

    Citation Envoyé par Chezkele Voir le message
    Etant donné que l'objectif de SAX est, sauf erreur de ma part, de récupérer le contenu de balises Xml, ce n'est pas terrible, non?
    Ce serait plutôt l'objectif de DOM.

    L'objectif de SAX, c'est de faire ça mais sans avoir à charger le contenu du fichier XML entièrement en mémoire. S'il te donnait l'entièreté de la balise, il la chargerait entièrement en mémoire pour mettre ce contenu dans une variable, n'est-ce pas ? Exactement ce que SAX sert à ne pas faire.

    Citation Envoyé par Chezkele Voir le message
    Qu'utilise-t-on en général pour remettre les choses bout à bout?
    La concaténation. Je crois qu'en PHP c'est avec le point . n'est-ce pas ?
    Ou si c'est trop gros, juste écrire à la suite dans un fichier ou dans une socket.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre confirmé
    Citation Envoyé par thelvin
    L'objectif de SAX, c'est de faire ça mais sans avoir à charger le contenu du fichier XML entièrement en mémoire
    Donc c'est bien à cela que cela sert, n'est-ce pas?

    Et quand on regarde, par exemple, l'exemple ci-dessous (source: https://www.tutorialspoint.com/php/p..._example.htm):

    Code PHP :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    <?php
       //Reading XML using the SAX(Simple API for XML) parser 
     
       $tutors   = array();
       $elements   = null;
     
       // Called to this function when tags are opened 
       function startElements($parser, $name, $attrs) {
          global $tutors, $elements;
     
          if(!empty($name)) {
             if ($name == 'COURSE') {
                // creating an array to store information
                $tutors []= array();
             }
             $elements = $name;
          }
       }
     
       // Called to this function when tags are closed 
       function endElements($parser, $name) {
          global $elements;
     
          if(!empty($name)) {
             $elements = null;
          }
       }
     
       // Called on the text between the start and end of the tags
       function characterData($parser, $data) {
          global $tutors, $elements;
     
          if(!empty($data)) {
             if ($elements == 'NAME' || $elements == 'COUNTRY' ||  $elements == 'EMAIL' ||  $elements == 'PHONE') {
                $tutors[count($tutors)-1][$elements] = trim($data);
             }
          }
       }
     
       // Creates a new XML parser and returns a resource handle referencing it to be used by the other XML functions. 
       $parser = xml_parser_create(); 
     
       xml_set_element_handler($parser, "startElements", "endElements");
       xml_set_character_data_handler($parser, "characterData");
     
       // open xml file
       if (!($handle = fopen('sax.xml', "r"))) {
          die("could not open XML input");
       }
     
       while($data = fread($handle, 4096)) // read xml file {
          xml_parse($parser, $data);  // start parsing an xml document 
       }
     
       xml_parser_free($parser); // deletes the parser
       $i = 1;
     
       foreach($tutors as $course) {
          echo "course No - ".$i.'<br/>';
          echo "course Name - ".$course['NAME'].'<br/>';
          echo "Country - ".$course['COUNTRY'].'<br/>';
          echo "Email - ".$course['EMAIL'].'<br/>';
          echo "Phone - ".$course['PHONE'].'<hr/>'; 
          $i++; 
       }
    ?>


    On voit que que le traitement réalisé dans la fonction characterData ne peut pas fonctionner si le contenu de la balise est livré en plusieurs fois n'est-ce pas? Il est donc légitime quand on cherche à faire quelque chose de similaire de chercher une solution n'est-ce pas?

  8. #8
    Modérateur

    Citation Envoyé par Chezkele Voir le message
    Donc c'est bien à cela que cela sert, n'est-ce pas?
    Oui c'est bien à cela que SAX sert, mais non, ce qui t'arrive ne montre pas spécialement que c'est pas très bien fait, puisque ça sert aussi à faire les choses comme ça au lieu de les faire autrement.
    Je me répète, mais si tu veux tes balises en une fois, DOM sert à ça. SAX sert à ne pas avoir ça.

    Citation Envoyé par Chezkele Voir le message
    On voit que que le traitement réalisé dans la fonction characterData ne peut pas fonctionner si le contenu de la balise est livré en plusieurs fois n'est-ce pas?
    C'est sûr, si les gens qui utilisent SAX savaient comment on programme avec, SAX serait beaucoup moins utilisé. Il ne devrait servir que pour très, très peu de situations. La plupart des gens qui choisissent SAX pour leur projet ne savent pas s'en servir, et ont donc mal fait leur programme, c'est exact.


    Citation Envoyé par Chezkele Voir le message
    Il est donc légitime quand on cherche à faire quelque chose de similaire de chercher une solution n'est-ce pas?
    C'est toujours légitime de se poser des questions, mais, la seule réponse est que SAX ne donne pas le contenu des balises en une fois. Lorsqu'il arrive qu'il les donne en une fois, ce n'est qu'un hasard amusant.
    Ceux qui programment avec SAX en pensant que la balise arrivera en une fois, font une erreur de programmation.
    Maintenant, c'est aussi le cas de la gestion des threads par exemple : il y a énormément d'applications qui programment très mal la gestion des threads, et pourtant elles fonctionnent... Du moins elles fonctionnent très très souvent. Ce n'est que parce qu'elles ne rentrent pas souvent dans un cas où la mauvaise gestion provoque un problème.
    C'est pareil. Toi tu es tombé sur un cas où la mauvaise gestion de SAX pose problème. C'est vrai que c'est pas de bol, alors que des bons millions d'autres font pas mieux et ils ne voient rien.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre confirmé
    Merci pour ta réponse, qui m'a permis de régler mon problème. J'ai lu plusieurs tutoriels sax avant de me lancer et tous les exemples cités ressemblaient à celui que j'ai donné plus haut, comme si effectivement le contenu était livré en une fois systématiquement, l'erreur vient de là.

###raw>template_hook.ano_emploi###