OVH Cloud OVH Cloud

ISO-8859-1

7 réponses
Avatar
Coucou2
Bonjour,
J'ai un formulaire sur un site web qui appel un script Perl.
celui-ci m'envoi des données par email.
Les données reçues me permettent de créer un fichier XML .
En voici l'entête:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="0.91">

J'ai un problème avec les accents et qq autres caractères non anglais...
Comment faire dans mon script perl pour les convertir correctement
ces caractères qui sont refusés par les lecteurs RSS ?

Ma version Perl est chez OVH 5.008008

J'ai déjà fait pas mal d'essais par:
$texte=~ tr/\80-\xff//CU;
ou

if ($] > 5.007) {
require Encode;
$nom = Encode::encode_utf8($nom); # make octets
}

Mais rien ne marche - je ne suis pas hélas un génie en Perl...
Merci de votre aide....

7 réponses

Avatar
Paul Gaborit
À (at) Mon, 9 Oct 2006 10:45:04 +0200,
"Coucou2" écrivait (wrote):
J'ai un formulaire sur un site web qui appel un script Perl.
celui-ci m'envoi des données par email.
Les données reçues me permettent de créer un fichier XML .
En voici l'entête:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="0.91">


Vous recevez donc des données dans un script CGI écrit en Perl et vous
envoyez ces données par mail. Mais avec quel encodage envoyez-vous ce
mail ? Puis vous reconstituez un fichier XML à partir de ce mail
reçu... Mais comment ? Ou alors c'est le fichier XML que vous envoyez
par mail ?

Ce n'est pas très clair.

J'ai un problème avec les accents et qq autres caractères non anglais...
Comment faire dans mon script perl pour les convertir correctement
ces caractères qui sont refusés par les lecteurs RSS ?

Ma version Perl est chez OVH 5.008008


Version inconnue au bataillon... À moins que ce ne soit la version
5.8.8 (mais représentée par l'ancienne variable $[). Dans ce cas,
utilisez plutôt la variable $^V qui est plus récente et plus propre :

printf "version is v%vdn", $^V;

J'ai déjà fait pas mal d'essais par:
$texte=~ tr/80-xff//CU;


Cela ne peut pas compiler avec une version récente de Perl. Les
options C et U ont disparu depuis la version 5.6.1.


if ($] > 5.007) {
require Encode;
$nom = Encode::encode_utf8($nom); # make octets
}


Vous voulez de l'ISO-8859-1. Alors pourquoi encodez-vous vos
caractères en UTF-8 ? Quelle est l'erreur que vous obtenez ?

Vous pouvez aussi laisser la tâche d'encodage au module qui génère le
XML (cela fait partie des choses qu'un module XML gère). Quel module
utilisez-vous pour générer le XML ?

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Coucou2
Merci de votre aide.
Je dois faire erreur ce qu'il me faut c'est du ISO-8859-1
Par ex: pour l'apostrophe, je dois mettre à la main : ... &#39;
sinon j'ai une erreur lorsque je te teste mon fichier chez FEED Validation
Service

A moins que d'après vous, il soit plus simple d'utiliser une autre norme
mais je ne sais pas si en xml version="1.0" c'est permis.

Je n'ai pas de module, mon script CGi fait le nécessaire pour les tags
<Item> etc...
Je conserve l'entête et copie/colle le code reçu directement par email
dans le fichier. De ce côté c'est facile très rapide et simple.

D'avance merci

--
Bonjour,

Merci de votre aide
Coucou
"Paul Gaborit" a écrit dans le message de
news:

À (at) Mon, 9 Oct 2006 10:45:04 +0200,
"Coucou2" écrivait (wrote):
J'ai un formulaire sur un site web qui appel un script Perl.
celui-ci m'envoi des données par email.
Les données reçues me permettent de créer un fichier XML .
En voici l'entête:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="0.91">


Vous recevez donc des données dans un script CGI écrit en Perl et vous
envoyez ces données par mail. Mais avec quel encodage envoyez-vous ce
mail ? Puis vous reconstituez un fichier XML à partir de ce mail
reçu... Mais comment ? Ou alors c'est le fichier XML que vous envoyez
par mail ?

Ce n'est pas très clair.

J'ai un problème avec les accents et qq autres caractères non anglais...
Comment faire dans mon script perl pour les convertir correctement
ces caractères qui sont refusés par les lecteurs RSS ?

Ma version Perl est chez OVH 5.008008


Version inconnue au bataillon... À moins que ce ne soit la version
5.8.8 (mais représentée par l'ancienne variable $[). Dans ce cas,
utilisez plutôt la variable $^V qui est plus récente et plus propre :

printf "version is v%vdn", $^V;

J'ai déjà fait pas mal d'essais par:
$texte=~ tr/80-xff//CU;


Cela ne peut pas compiler avec une version récente de Perl. Les
options C et U ont disparu depuis la version 5.6.1.


if ($] > 5.007) {
require Encode;
$nom = Encode::encode_utf8($nom); # make octets
}


Vous voulez de l'ISO-8859-1. Alors pourquoi encodez-vous vos
caractères en UTF-8 ? Quelle est l'erreur que vous obtenez ?

Vous pouvez aussi laisser la tâche d'encodage au module qui génère le
XML (cela fait partie des choses qu'un module XML gère). Quel module
utilisez-vous pour générer le XML ?

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>



Avatar
Paul Gaborit
À (at) Mon, 9 Oct 2006 20:09:48 +0200,
"Coucou2" écrivait (wrote):
Je dois faire erreur ce qu'il me faut c'est du ISO-8859-1
Par ex: pour l'apostrophe, je dois mettre à la main : ... &#39;
sinon j'ai une erreur lorsque je te teste mon fichier chez FEED Validation
Service


Là, vous mélangez deux notions : le jeu de caractères et l'encodage.

"&#39;" c'est une entité numérique HTML qui n'utilise pour sa
représentation que des caractères ASCII.

Cette entité représente le caractère dont le code est 39 (en décimal)
dans le jeu de caractères du HTML (Unicode).

En XML, vous pourriez aussi utiliser "&#x27;" (valeur exprimée en
hexadécimal).

Il se trouve que 39, c'est aussi la valeur utilisée par la quasi
totalité des encodages pour représenter une apostrophe (tous ceux
basés sur l'ASCII).

Prenons un exemple plus compliqué. Si vous souhaitez insérer un e
accent aigu. Ce caractère existe dans le jeu de caractère Unicode
(code décimal 233).

Vous pouvez toujours représenter ce caractère par l'entité numérique
"&#233;".

Mais vous pouvez aussi utiliser l'encodage directement si il
l'autorise.

- Si l'encodage choisi est ASCII (qui ne contient pas le e accent
aigu) alors vous êtes obligé d'utiliser l'entité numérique "&#233;".

- Si l'encodage choisi est ISO-8859-1 (qui contient le e accent
aigu) alors vous pouvez utiliser l'entité numérique "&#233;" ou
directement "é" encodé en ISO-8859-1 : l'octet 0xE9.

- Si l'encodage choisi est UTF-8 (qui contient le e accent aigu)
alors vous vous pouvez utiliser l'entité numérique "&#233;" ou
directement le "é" mais codé en UTF-8 : les deux octets 0xC3A9.

J'ai mis de côté les entités nommées (qui sont pratiques car (presque)
lisibles par l'homme) car il faut que votre DTD ou votre Schéma XML
les définissent ce qui n'est pas toujours le cas.

Les entités numériques sont exprimées en base dix et correspondent au
numéro de caractères Unicode.

Le codage direct utilise le codage choisi pour le document et donc a
les mêmes limites que cet encodage (évidemment).

A moins que d'après vous, il soit plus simple d'utiliser une autre norme
mais je ne sais pas si en xml version="1.0" c'est permis.


Ça dépend de l'encodage qui suit dans votre en-tête XML.

Si vous ne souhaitez pas utiliser un encodage particulier en dehors de
l'ASCII, vous pouvez utiliser Encode pour faire le boulot :


use Encode;

binmode STDOUT, ":encoding(ascii)"; # On n'utilise que de l'ASCII en sortie

my $str = "L'été est chaud. x{263A} ©n";

my $html_str = encode("ascii", $str, Encode::FB_HTMLCREF);
my $xml_str = encode("ascii", $str, Encode::FB_XMLCREF);

print $html_str;
print $xml_str;

qui vous affichera :

L'&#233;t&#233; est chaud. &#9786; &#169;
L'&#xe9;t&#xe9; est chaud. &#x263a; &#xa9;

À vous de choisir si vous voulez du HTML ou du XML.

PS: le caractère Unicode x{263A} est un smiley souriant.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Coucou2
Bonjour,
merci de votre mais c'est pas facile....
Voici ce que je mets suivant vos conseils dans mon script cgi:

my $str ="a'éç ' »";
use Encode;
binmode STDOUT, ":encoding(ascii)";
my $xml_str = encode("ascii", $str, Encode::FB_XMLCREF);
print $xml_str;

Je récupère:
a'&#xe9;&#xe7; &#x92; &#xbb;

Je place le tout dans mon fichier xml dans l'item description

Lorsque je teste sur http://validator.w3.org/feed/
J'obtiens une erreur bad characters sur &#x92;
Les autres passent....

Vous avez une idée merci....

--
Bonjour,

Merci de votre aide
Coucou
"Paul Gaborit" a écrit dans le message de
news:

À (at) Mon, 9 Oct 2006 20:09:48 +0200,
"Coucou2" écrivait (wrote):
Je dois faire erreur ce qu'il me faut c'est du ISO-8859-1
Par ex: pour l'apostrophe, je dois mettre à la main : ... &#39;
sinon j'ai une erreur lorsque je te teste mon fichier chez FEED
Validation


Service


Là, vous mélangez deux notions : le jeu de caractères et l'encodage.

"&#39;" c'est une entité numérique HTML qui n'utilise pour sa
représentation que des caractères ASCII.

Cette entité représente le caractère dont le code est 39 (en décimal)
dans le jeu de caractères du HTML (Unicode).

En XML, vous pourriez aussi utiliser "&#x27;" (valeur exprimée en
hexadécimal).

Il se trouve que 39, c'est aussi la valeur utilisée par la quasi
totalité des encodages pour représenter une apostrophe (tous ceux
basés sur l'ASCII).

Prenons un exemple plus compliqué. Si vous souhaitez insérer un e
accent aigu. Ce caractère existe dans le jeu de caractère Unicode
(code décimal 233).

Vous pouvez toujours représenter ce caractère par l'entité numérique
"&#233;".

Mais vous pouvez aussi utiliser l'encodage directement si il
l'autorise.

- Si l'encodage choisi est ASCII (qui ne contient pas le e accent
aigu) alors vous êtes obligé d'utiliser l'entité numérique "&#233;".

- Si l'encodage choisi est ISO-8859-1 (qui contient le e accent
aigu) alors vous pouvez utiliser l'entité numérique "&#233;" ou
directement "é" encodé en ISO-8859-1 : l'octet 0xE9.

- Si l'encodage choisi est UTF-8 (qui contient le e accent aigu)
alors vous vous pouvez utiliser l'entité numérique "&#233;" ou
directement le "é" mais codé en UTF-8 : les deux octets 0xC3A9.

J'ai mis de côté les entités nommées (qui sont pratiques car (presque)
lisibles par l'homme) car il faut que votre DTD ou votre Schéma XML
les définissent ce qui n'est pas toujours le cas.

Les entités numériques sont exprimées en base dix et correspondent au
numéro de caractères Unicode.

Le codage direct utilise le codage choisi pour le document et donc a
les mêmes limites que cet encodage (évidemment).

A moins que d'après vous, il soit plus simple d'utiliser une autre norme
mais je ne sais pas si en xml version="1.0" c'est permis.


Ça dépend de l'encodage qui suit dans votre en-tête XML.

Si vous ne souhaitez pas utiliser un encodage particulier en dehors de
l'ASCII, vous pouvez utiliser Encode pour faire le boulot :


use Encode;

binmode STDOUT, ":encoding(ascii)"; # On n'utilise que de l'ASCII en
sortie


my $str = "L'été est chaud. x{263A} ©n";

my $html_str = encode("ascii", $str, Encode::FB_HTMLCREF);
my $xml_str = encode("ascii", $str, Encode::FB_XMLCREF);

print $html_str;
print $xml_str;

qui vous affichera :

L'&#233;t&#233; est chaud. &#9786; &#169;
L'&#xe9;t&#xe9; est chaud. &#x263a; &#xa9;

À vous de choisir si vous voulez du HTML ou du XML.

PS: le caractère Unicode x{263A} est un smiley souriant.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>



Avatar
Paul Gaborit
À (at) Tue, 10 Oct 2006 20:35:03 +0200,
"Coucou2" écrivait (wrote):
Bonjour,
merci de votre mais c'est pas facile....
Voici ce que je mets suivant vos conseils dans mon script cgi:

my $str ="a'éç ' »";
use Encode;
binmode STDOUT, ":encoding(ascii)";
my $xml_str = encode("ascii", $str, Encode::FB_XMLCREF);
print $xml_str;

Je récupère:
a'&#xe9;&#xe7; &#x92; &#xbb;

Je place le tout dans mon fichier xml dans l'item description

Lorsque je teste sur http://validator.w3.org/feed/
J'obtiens une erreur bad characters sur &#x92;
Les autres passent....


C'est normal.

($str = "a'eç x{92} »";)
-----

Regardez votre texte $str. Il contient deux apostrophes. La première
est laissée en l'état (c'est l'apostrophe standard de l'ASCII) alors
que l'autre est encodée en "&#x92;" et n'est pas acceptée par le
validateur. Et c'est normal, car ce n'est pas un caractère Unicode
(cf. <http://www.w3.org/TR/REC-xml/#NT-Char>, dans la table finale de
la section).

En fait, cette apostrophe est une apostrophe encodée en cp1250 (le
codage utilisé par Windows). Perl l'accepte parce que c'est un
caractère de code inférieur à 256 (< x{100}) et donc potentiellement
un octet. Et donc pour des raisons de compatibilités.

Mais XML est plus exigeant. Il vous faudra donc convertir ce caractère
(et d'autres qui sont spécifiques au codage Windows cp1250) en un
caractère correct pour Unicode. En se posant la question : est-ce une
apostrophe ? un prime ? un apostrophe qui fonctionne en paire ouvrante
fermante ? La réponse vous permettra de choisir le bon caractère
Unicode.

En attendant, vous pouvez toujours traiter ce cas particulier par :

$str =~ tr/x{92}/'/;

avant de faire l'encodage.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Coucou2
Merci,

J'ai repris votre ligne $str =~ tr/x{92}/'/;
Cela marche "évidemment" très bien pour l'apostrophe récalcitrante...
J'espère qu'il n'y aura pas trop de caractères avec ce problème,
je suppose qu'il me faudra les traiter un à un ce qui risque de ralentir
l'exécution de mon script...

Y a-t'il un truc pour connaître les caractères qui vont me poser problème?

Coucou

"Paul Gaborit" a écrit dans le message de
news:

À (at) Tue, 10 Oct 2006 20:35:03 +0200,
"Coucou2" écrivait (wrote):
Bonjour,
merci de votre mais c'est pas facile....
Voici ce que je mets suivant vos conseils dans mon script cgi:

my $str ="a'éç ' »";
use Encode;
binmode STDOUT, ":encoding(ascii)";
my $xml_str = encode("ascii", $str, Encode::FB_XMLCREF);
print $xml_str;

Je récupère:
a'&#xe9;&#xe7; &#x92; &#xbb;

Je place le tout dans mon fichier xml dans l'item description

Lorsque je teste sur http://validator.w3.org/feed/
J'obtiens une erreur bad characters sur &#x92;
Les autres passent....


C'est normal.

($str = "a'eç x{92} »";)
-----

Regardez votre texte $str. Il contient deux apostrophes. La première
est laissée en l'état (c'est l'apostrophe standard de l'ASCII) alors
que l'autre est encodée en "&#x92;" et n'est pas acceptée par le
validateur. Et c'est normal, car ce n'est pas un caractère Unicode
(cf. <http://www.w3.org/TR/REC-xml/#NT-Char>, dans la table finale de
la section).

En fait, cette apostrophe est une apostrophe encodée en cp1250 (le
codage utilisé par Windows). Perl l'accepte parce que c'est un
caractère de code inférieur à 256 (< x{100}) et donc potentiellement
un octet. Et donc pour des raisons de compatibilités.

Mais XML est plus exigeant. Il vous faudra donc convertir ce caractère
(et d'autres qui sont spécifiques au codage Windows cp1250) en un
caractère correct pour Unicode. En se posant la question : est-ce une
apostrophe ? un prime ? un apostrophe qui fonctionne en paire ouvrante
fermante ? La réponse vous permettra de choisir le bon caractère
Unicode.

En attendant, vous pouvez toujours traiter ce cas particulier par :

$str =~ tr/x{92}/'/;

avant de faire l'encodage.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>



Avatar
Paul Gaborit
À (at) Thu, 12 Oct 2006 15:02:16 +0200,
"Coucou2" écrivait (wrote):
J'ai repris votre ligne $str =~ tr/x{92}/'/;
Cela marche "évidemment" très bien pour l'apostrophe récalcitrante...
J'espère qu'il n'y aura pas trop de caractères avec ce problème,
je suppose qu'il me faudra les traiter un à un ce qui risque de ralentir
l'exécution de mon script...


L'instruction que je vous donne peut-être enrichie (tant qu'on associe
un seul caractère Windows cp1252 à un seul caractère Unicode). Par
exemple, dans cp1252 on trouve des guillemets (") associées au code
0x94 ou le caractère 'euro' associé au code 0x80.

Vous pouvez donc enrichir votre instruction par :

$str =~ tr/x{80}x{92}x{94}/x{20AC}'"/;

(L'euro en Unicode est x{20AC}.)

L'idéal serait de savoir si votre texte initial est codé complètement
en cp1252. Dans ce cas, le plus simple serait d'utiliser Encode (ou
les filtres d'entrées/sorties) pour réaliser la transformation
complètement en une seule fois.

Un truc du genre :

# $str est codé en Windows cp1252
$str = decode("cp1252", $str);
# $str est codé en UTF-8

Les bonnes questions sont donc :
- Comment récupérez-vous vos données ?
- Comment faites-vous pour savoir le codage qu'elles utilisent ?

Y a-t'il un truc pour connaître les caractères qui vont me poser problème?


Portentiellement, tous les caractères (en dehors de l'ASCII) peuvent
poser problème. Mais pour mieux voir la différence, regardez la table
suivante :

<http://en.wikipedia.org/wiki/Windows-1252>

Les caractères à fond jaunes posent problème à tous les coups car ils
ne correspondent pas à de l'iso-8859-1 (par défaut et pour des raisons
de compatibilités, Perl suppose que les données externes sont en
iso-8859-1).

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>