Comment déterminer si un flux XML est codé en UTF8

Olivier Duffez (admin)
Membre du personnel
Tout est dans le titre (eh oui, c'est mieux de bien choisir les titres...) : je cherche à savoir comment déterminer de manière automatique si un flux XML (RSS ou Atom) est codé en UTF8 (auquel cas je dois appliquer la fonction utf8_decode).

J'imagine que la question serait la même pour l'analyse d'une page HTML mais là je rencontre ce problème sur un flux XML.
 
WRInaute discret
Code:
function is_utf8($string) {
  
   // From http://w3.org/International/questions/qa-forms-utf-8.html
   return preg_match('%^(?:
         [\x09\x0A\x0D\x20-\x7E]            # ASCII
       | [\xC2-\xDF][\x80-\xBF]            # non-overlong 2-byte
       |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
       | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
       |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
       |  \xF0[\x90-\xBF][\x80-\xBF]{2}    # planes 1-3
       | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
       |  \xF4[\x80-\x8F][\x80-\xBF]{2}    # plane 16
   )*$%xs', $string);
  
}
 
WRInaute discret
sinon en analysant les headers que renvoit le serveur distant, logiquement il renvoit Content-Type: text/html; charset=utf8 si c'est en utf8 dans le header.
 
WRInaute impliqué
Un fichier XML par défaut est en UTF-8, sinon il doit y avoir une spécification d'encodage du genre
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>

S'il n'y a pas d'encodage précisé et que celui-ci n'est pas en UTF-8, le fichier XML n'est pas valide.

Sinon, il y a cette fonction PHP pour déterminer si un fichier est en UTF-8
Code:
function seems_utf8($Str) {
        for ($i=0; $i<strlen($Str); $i++) {
            if (ord($Str[$i]) < 0x80) $n=0; # 0bbbbbbb
            elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
            elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
            elseif ((ord($Str[$i]) & 0xF0) == 0xF0) $n=3; # 1111bbbb
            else return false; # Does not match any model
  
            for ($j=0; $j<$n; $j++) { # n octets that match 10bbbbbb follow ?
                if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80)) return false;
            }
        }
        return true;
    }
 
Olivier Duffez (admin)
Membre du personnel
@Orion33 et shrom : merci pour les fonctions, je les utiliserai sans doute dans d'autres cas.

@spijoelx : non, j'ai trouvé des exemples de fichiers UTF-8 où le header ne contient pas charset=utf8

@shrom : merci pour ta 1ère réponse pleine de bon sens, effectivement il suffit que je récupère l'attribut encoding de la balise xml.

Je vais chercher dans magpierss-0.71.1 (version que je n'avais pas encore installée) si l'info de l'encodage est accessible via magpierss. En fait je suis étonné de voir que j'ai besoin de me préoccuper de ce décodage sachant que j'utilise magpierss (je dois faire un truc de travers sans doute).

edit : c'est bon ça marche maintenant... ma version de magpierss était trop vieille peut-être
 
WRInaute discret
il me semble que la librairie DOM de php5 gere le XML en UTF-8 nativement.
Donc, lorsque l'on parse un fichier encode en windows-1251 par exemple, la classe DomDocument renvoit du utf-8 et il faut appliquer utf8_decode pour le transformer en ISO-8859-1
 
Discussions similaires
Haut