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

Bibliothèques et frameworks PHP Discussion :

[XML] XML et UTF-8


Sujet :

Bibliothèques et frameworks PHP

  1. #1
    Membre régulier Avatar de miniil
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 267
    Points : 76
    Points
    76
    Par défaut [XML] XML et UTF-8
    Bonjour,

    J'essaye de lire un flux XML et de parser celui-ci afin d'enregistrer les données dans la DB de mon application.

    J'ai donc :
    1. Un script php qui construit mon flux XML
    2. Un programme Java qui appelle l'url de ce script et qui doit parser le flux XML reçu.

    La script php construit le flux XML en exécutant une requête sur une DB Mysql encodé en UTF-8. Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    <?php
    header('Content-Type: text/xml; charset=UTF-8');
    $xml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
     
    $xml .= '<rprodlist>';
    $sql = 'SELECT 100R_ID, 100R_TYPE, 100R_MARQUE, 100R_NOMPROD, 100R_PRIX, 100R_DATELIMITE, 100R_COUPON, 100R_INFOCOMPL, 100R_ADRESSE, 100R_END '
         . 'FROM phpbb3_100R '
    	 . 'WHERE 100R_END = 0';
     
    //echo "DEBUG sql = " . $sql;
     
    if(!$result = $db->sql_query($sql))
    //if(!$result = $db->sql_query_limit($sql,5))
    {
    	trigger_error("Erreur SQL");               
    }
     
    function parseForEuro($text)
    {
    	//echo "<br/>Texte avant : " . $text;
    	$text = str_replace ( "€", "€", $text);
    	return $text;
    }
     
    while($row = $db->sql_fetchrow($result))
    {
    	$id = $row['100R_ID'];
    	$type = $row['100R_TYPE'];
    	$marque = $row['100R_MARQUE'];
    	$nomprod = $row['100R_NOMPROD'];
    	$prix = parseForEuro($row['100R_PRIX']);
    	$datelimite = $row['100R_DATELIMITE'];
    	$coupon = $row['100R_COUPON'];
    	$infocompl = parseForEuro($row['100R_INFOCOMPL']);
    	$adresse = $row['100R_ADRESSE'];
    	$end = $row['100R_END'];
     
    	//echo $infocompl;
    	$xml .= '<item>';
    	$xml .= '<id>'.$id.'</id>';
    	$xml .= '<type>'.$type.'</type>';
    	$xml .= '<marque>'.$marque.'</marque>';
    	$xml .= '<nomprod>'.$nomprod.'</nomprod>';
    	$xml .= '<prix>'.$prix.'</prix>';
    	$xml .= '<datelimite>'.$datelimite.'</datelimite>';
    	$xml .= '<coupon>'.$coupon.'</coupon>';
    	$xml .= '<infocompl>'.$infocompl.'</infocompl>';
    	$xml .= '<adresse>'.$adresse.'</adresse>';
    	$xml .= '<end>'.$end.'</end>';
    	$xml .= '</item>';	
     
    }
     
     
    $xml .= '</rprodlist>';
    echo $xml;
     
    $db->sql_freeresult($result);
    ?>
    et mon code Java qui récupère le flux XML et le parse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     try
            {
                DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                URL u = new URL("http://www.xxx.fr/xxx.php"); 
     
     
                Document doc = builder.parse(u.openStream());
                NodeList nodes = doc.getElementsByTagName("item");
     
                for(int i=0;i<nodes.getLength();i++)
                {
                }
     
    ...
    Alors mon soucis est que de cette manière, je récupère bien les données de mon flux mais les accents sont tous encodés avec des caractères spéciaux.

    Par contre si j'affiche mon flux XML dans un navigateur, mes accents sont corrects.

    Si je modifie, la ligne
    $xml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
    en
    $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

    j'ai alors une erreur lors du parsing.


    Pouvez-vous me dire comment récupérer ou convertir le flux reçu afin de pouvoir enregistrer mes données avec des accents corrects dans la DB de mon programme Java.

    D'avance merci.
    miniil

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par miniil Voir le message

    Si je modifie, la ligne
    $xml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
    en
    $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

    j'ai alors une erreur lors du parsing.
    Quelle erreur? Si tu a généré une réponse en UTF-8, alors ton entête xml doit être UTF-8. Dans le code que tu montre il y a clairement contradiction entre le header http et le header xml. Un navigateur a accès au header http, il l'utilisera, les parseur xml de java ne recois que le contenu du xml, il devrai donc se contenter de l'instruction xml. Peux tu attacher le fichier xml généré qu'on vois dans quel encodage il est réellement?

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 608
    Points
    21 608
    Par défaut
    Citation Envoyé par miniil Voir le message
    Pouvez-vous me dire comment récupérer ou convertir le flux reçu afin de pouvoir enregistrer mes données avec des accents corrects dans la DB de mon programme Java.
    Pour répondre à cette question-là :

    1 - choisir un charset et un seul. ISO-8859-1 ou UTF-8, comme on veut, mais en choisir un et s'y tenir.
    2 - utiliser effectivement ce charset, et pas un autre, pour générer le flux.
    3 - déclarer ce charset, dans le header HTTP, et dans la déclaration XML, à l'identique. En fait, ce n'est pas nécessaire de le déclarer dans le header HTTP. Mais quand on le fait quand même, ça doit être bien fait.

    Nous remarquerons au passage que tout cela se fait côté php, éventuellement côté base de données source, mais pas du tout côté Java. En effet le parseur va se débrouiller tout seul avec la déclaration XML, à condition bien sûr qu'elle soit correcte.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre régulier Avatar de miniil
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 267
    Points : 76
    Points
    76
    Par défaut
    L'erreur était celle-ci :

    com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.

    Ca me fait penser qu'un caractère dans le flux est incorrect, mais pour trouver lequel c'est pas gagner.

    J'ai joint le fichier XML en question.
    Fichiers attachés Fichiers attachés
    miniil

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 608
    Points
    21 608
    Par défaut
    Marrant. Ce fichier :

    - Se déclare être en ISO-8859-1 dans la déclaration XML
    - Est presque entièrement en UTF-8
    - A ses symboles € encodés en windows-1252 (un sur-ensemble de ISO-8859-1, et donc incompatible UTF-8)

    Par conséquent, tel que, le parseur Java va le lire en ISO-8859-1, probablement remplacer les € par des ?, et les accents, étant mal encodés, seront donc sous la forme é.

    Et si on le déclare comme UTF-8 dans la déclaration XML, le symbole €, mal encodé, va entraîner la fameuse MalformedByteSequenceException.
    (Normalement, un navigateur se base sur le header HTTP, utilise donc UTF-8, et devrait générer le même genre d'erreur. Il est possible que le navigateur utilisé ait été permissif sur le mauvais encodage du symbole €, mais c'est une erreur de compatibilité de sa part.)

    Conformément à mes remarques plus haut, solution, au choix :
    - encoder correctement le symbole € en UTF-8, et déclarer le fichier comme étant UTF-8.
    OU
    - encoder tout le fichier en windows-1252, et déclarer le fichier comme étant windows-1252.
    OU
    - remplacer le symbole euro par son entité XML qui est &#x20AC; et déclarer le fichier comme étant UTF-8.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    le contenu du fichier est bien en utf-8, a l'exception de certains caractère particuliers que le php a eu du mal à manger. Je pense particulièrement à

    Vu dans la pub du Blokker page 6



    50% retour => Retour sur votre compte en banque 10€
    (caractère 0x80 à la fin)

    Le caractère est en binaire 10000000

    Hors, en UTF-8 les séquences possibles sont
    0xxxxxxx 1 octet codant 1 à 7 bits
    110xxxxx 10xxxxxx 2 octets codant 8 à 11 bits
    1110xxxx 10xxxxxx 10xxxxxx 3 octets codant 12 à 16 bits
    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4 octets codant 17 à 21 bits

    Est-ce que PHP fait bien sont output correctement en utf-8? Aurais-tu une crasse dans la DB? Dans tous les cas, ca ne concerne pas java ce problème.

    edit: et je ne suis pas d'accord, les € sont bien en utf-8 Ouvrir un éditeur hexa et retirer ce 0x80 est suffisant pour pouvoir ouvrir le fichier en utf-8

  7. #7
    Membre régulier Avatar de miniil
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 267
    Points : 76
    Points
    76
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Marrant. Ce fichier :

    - Se déclare être en ISO-8859-1 dans la déclaration XML
    - Est presque entièrement en UTF-8
    - A ses symboles € encodés en windows-1252 (un sur-ensemble de ISO-8859-1, et donc incompatible UTF-8)
    Je pense que ceci vient du fait que les données dans la DB Mysql sont enregistrées comme ça. Avec les accents en UTF-8.

    REM : Il s'agit d'une table du CMC phpBB.

    Conformément à mes remarques plus haut, solution, au choix :

    Encoder correctement le symbole € en UTF-8, et déclarer le fichier comme étant UTF-8.
    Je ne sais pas si ceci sera facilement réalisable puisque les données proviennent d'une table du CMS phpBB et que sont contenu est donc le résultat des messages postés par les membres du forum.

    encoder tout le fichier en windows-1252, et déclarer le fichier comme étant windows-1252.
    Puis-je faire ça avec les données de la base de données MySQL en UTF-8?

    remplacer le symbole euro par son entité XML qui est &#x20AC; et déclarer le fichier comme étant UTF-8.
    Ca je l'ai fait, d'ailleurs on le voit dans mon code php du premier message sauf que le caractère que j'ai indiqué pour euro était celui en hexadécimal (dans mon message il a été interprété).
    Mais ça ne fonctionnait pas mieux puisque j'avais toujours l'erreur citée.
    Je me dis qu'il existe peut-être d'autres caractères que € qui posent problème mais lesquels
    miniil

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    problème lié à PHP, je déplace

  9. #9
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 608
    Points
    21 608
    Par défaut
    Citation Envoyé par miniil Voir le message
    Je pense que ceci vient du fait que les données dans la DB Mysql sont enregistrées comme ça. Avec les accents en UTF-8.

    REM : Il s'agit d'une table du CMC phpBB.
    Mon PHP date de loin, mais il me semble que ça marche comme ça, oui.

    Encoder correctement le symbole € en UTF-8, et déclarer le fichier comme étant UTF-8.
    Je ne sais pas si ceci sera facilement réalisable puisque les données proviennent d'une table du CMS phpBB et que sont contenu est donc le résultat des messages postés par les membres du forum.
    Je ne sais pas si ceci sera facilement réalisable puisque les données proviennent d'une table du CMS phpBB et que sont contenu est donc le résultat des messages postés par les membres du forum.
    Bah ? Ce serait quoi, le problème ?

    encoder tout le fichier en windows-1252, et déclarer le fichier comme étant windows-1252.
    Puis-je faire ça avec les données de la base de données MySQL en UTF-8?
    Alors, j'ai beau pester contre les nombreuses erreurs de ce langage qu'est PHP, je suis sûr qu'il est quand même capable de transcoder à la volée un texte d'un charset vers un autre. Au pire, il y a forcément une bibliothèque qui en est capable.

    remplacer le symbole euro par son entité XML qui est &#x20AC; et déclarer le fichier comme étant UTF-8.
    Ca je l'ai fait, d'ailleurs on le voit dans mon code php du premier message sauf que le caractère que j'ai indiqué pour euro était celui en hexadécimal (dans mon message il a été interprété).
    L'hexadécimal, c'est celui que j'ai donné moi. Je l'ai donné comme ça justement parce que le forum n'interprète pas la forme hexadécimale. Il est probable que tu aies donné la forme décimale et que le forum l'a interprété.
    Sauf que... Si c'était ce que tu avais fait, ça marcherait très bien et il n'y aurait que le problème des accents.

    Mais ça ne fonctionnait pas mieux puisque j'avais toujours l'erreur citée.
    Dans le fichier que tu nous a montré, le symbole € n'est pas échappé par une entité.

    Je me dis qu'il existe peut-être d'autres caractères que € qui posent problème mais lesquels
    la seule question qu'on peut se poser, c'est pourquoi € pose problème, et éventuellement pourquoi pas les autres ? Les caractères ne se mettent pas à poser problème comme ça, spontanément.
    Je t'ai déjà fait une remarque, toutefois : ton fichier se déclare ISO-8859-1, est en UTF-8, et le symbole € y est encodé en windows-1252, la raison étant sans doute qu'il n'existe pas en ISO-8859-1. D'autres symboles dans ce même cas sont par exemple œ et Œ.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Membre régulier Avatar de miniil
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 267
    Points : 76
    Points
    76
    Par défaut
    En effet, je viens de trouver les caractères en plus du caractères € qui posaient problème.

    Il s'agissait des caractères apostrophe et tiret qui avaient été écrit d'une autre manière : ─ pour le tiret (alt+196) et l'apostrophe j'ai pas trouvé, c'était une apostrophe penchée ?!?
    miniil

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    je répète, la sortie était en bon utf-8, à l'exception d'un seul octet (voir mon message précédent). Voir donc pourquoi cet octet est incorrect lors de l'envoi vers echo (PHP devrais sortir un utf-8 correct). Les spécialiste PHP répondront

Discussions similaires

  1. ecrire un fichier xml encodage UTF-8
    Par totoche dans le forum Langage
    Réponses: 4
    Dernier message: 09/10/2009, 17h07
  2. [BOM] Supprimer le BOM d'un xml en UTF-8
    Par kij dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 22/11/2007, 11h46
  3. instruction pour xml Encoder utf-8
    Par totoche dans le forum ASP
    Réponses: 7
    Dernier message: 14/02/2007, 11h03
  4. Cobol , XML et UTF-8
    Par unknownuser dans le forum Cobol
    Réponses: 3
    Dernier message: 26/11/2006, 21h29
  5. [File][UTF-16]comment creer un fichier xml en utf-16?
    Par Invité dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 10/01/2006, 15h40

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