détection encoding fichier xml

WRInaute discret
Bonjour

je voudrais détecter l'encodage d' un fichier xml (utf-8, iso-8859-1) via un script ou une fonction php, j'ai beau chercher sur la toile, j'ai rien vu d'intéressant, si quelqu’un à un exemple ou une piste pour résoudre mon problème je suis preneur.
 
Nouveau WRInaute
Salut,

xanti a dit:
je voudrais détecter l'encodage d' un fichier xml (utf-8, iso-8859-1) via un script ou une fonction php, j'ai beau chercher sur la toile, j'ai rien vu d'intéressant, si quelqu’un à un exemple ou une piste pour résoudre mon problème je suis preneur.

A moins que l'encodage soit explicitement donné dans le header XML ou dans le Content-Type si le fichier XML est obtenu via HTTP, il n'y a pas toujours de moyen de savoir à 100% si un fichier est encodé en UTF-8 ou en ISO-8859-1.

Ce qu'il est possible, c'est d'éliminer la possibilité qu'un fichier soit en UTF-8 en vérifiant qu'il est correctement encodé: certaines séquences de caractères ne sont pas possibles en UTF-8 alors qu'elles le sont en ISO.

Petit bout de perl qui fait ça:
Code:
# returns 0 if the string is definitely NOT UTF-8
# returns 1 if the string may very well be UTF-8 (but this is not 100% sure)

sub check_utf8
{
        my ($word)      =       @_;
        return 0 if (!defined $word);
        my (@c) =       split //,$word;
        my ($c);

        while (defined ($c = shift @c))
        {
                $c      =       ord     $c;
                if ($c >= 0xc0 && $c <= 0xdf)
                {
                        $c      =       ord shift @c;
                        return 0 if ($c<0x80 || $c >0xbf);
                }
                elsif ($c >= 0xe0 && $c <= 0xef)
                {
                        $c      =       ord shift @c;
                        return 0 if ($c<0x80 || $c >0xbf);
                        $c      =       ord shift @c;
                        return 0 if ($c<0x80 || $c >0xbf);
                }
                elsif ($c >= 0xf0 && $c <= 0xf7)
                {
                        $c      =       ord shift @c;
                        return 0 if ($c<0x80 || $c >0xbf);
                        $c      =       ord shift @c;
                        return 0 if ($c<0x80 || $c >0xbf);
                        $c      =       ord shift @c;
                        return 0 if ($c<0x80 || $c >0xbf);
                }
                elsif (($c >= 0x80 && $c <=0xbf) || ($c >= 0xf8))
                {
                        return 0;
                }
        }
        return 1;
}

J'ai écrit ça il y a un bout de temps donc ce n'est probablement pas optimal du tout, mais bon, ça marche :)

Si la fonction renvoie 0, on est sur que ce n'est pas de l'UTF-8, donc a priori (dans nos contrées) c'est de l'ISO-8859-1 (mais n'importe où ailleurs ça peut être un peu n'importe quel jeu de caractères). Si la fonction renvoie 1, ça peut être de l'UTF-8 (et dans nos contrées, il y a de fortes chances que c'en soit, ça fait des choses assez bizarres en ISO-8859-1 en général), mais ce n'est pas garanti (et dans certains jeux de caractères c'est tout à fait possible que ce n'en soit pas).

Evidemment plus le texte est long, plus la probabilité est forte, mais bon.

Jacques.
 
Discussions similaires
Haut