2009-10-21 8 views
0

Le morceau de code suivant (coupé par souci de brièveté) génère un document xml et le recrache dans un fichier. Si j'ouvre le fichier dans Visual Studio, il semble être en caractères chinois. Si je l'ouvre dans le Bloc-notes, il semble comme prévu. Si je Console.WriteLine il semble correct.ne peut pas comprendre ces malheurs de codage xml

Je sais que c'est lié au codage, mais je pensais que j'avais tous les canards d'encodage dans une rangée. Qu'est-ce qui manque?

StringBuilder stringBuilder = new StringBuilder(); 
XmlWriterSettings settings = new XmlWriterSettings(); 
settings.Encoding = Encoding.Unicode; 
settings.Indent = true; 
settings.IndentChars = "\t"; 
using (XmlWriter textWriter = XmlWriter.Create(new StringWriter(stringBuilder), settings)) 
{ 
    textWriter.WriteStartElement("Submission"); 
    textWriter.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); 
    textWriter.WriteEndElement(); 
} 

using (StreamWriter sw = new StreamWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))) 
      { 
       sw.Write(stringBuilder.ToString()); 
      } 

Répondre

2

Le problème est que vous écrivez à disque en utilisant UTF-8, mais il réclamation être UTF-16 parce que c'est ce qu'un StringWriter utilise par défaut - et parce que vous êtes en définissant explicitement pour utiliser également Encoding.Unicode.

La façon la plus simple de résoudre ce problème est d'utiliser un StringWriter qui s'annonce comme UTF-8:

public class Utf8StringWriter : StringWriter 
{ 
    public override Encoding 
    { 
     get { return Encoding.UTF8; } 
    } 
} 

... puis retirez la ligne settings.Encoding = Encoding.Unicode. De cette façon, vous utiliserez UTF-8 partout. (En fait, la propriété Encoding de XmlWriterSettings est ignoré lorsque vous créez le XmlWriter avec un TextWriter de toute façon.)

Si vous avez vraiment voulez UTF-16, puis lorsque vous créez l'y StreamWriter, spécifiez Encoding.Unicode aussi.

+0

Donc le résultat du StringWriter est une chaîne unicode de 16 bits et qui sera encodée avec UTF-8, puis écrite sur le disque? –

+0

Eh bien, le résultat de StringWriter sera une chaîne unicode quoi qu'il arrive, car c'est ce que .NET utilise comme format de chaîne. Le problème est que la déclaration XML au début du fichier indiquera qu'il utilise UTF-16, même s'il utilise vraiment UTF-8. –

+0

J'ai fini par ajouter Encoding.Unicode comme second paramètre sur le constructeur StringWriter. Cela semble avoir fait l'affaire. En quoi cela diffère-t-il de votre approche de dérivation de StringWriter? –

0

Je ne suis pas sûr ce que Encoding.Unicode est mais je suppose que c'est UTF-16 qui écrit deux octets par caractère dans le fichier. Pour le texte ASCII normal, l'un des octets est toujours 0.

Essayez plutôt UTF-8. Cela devrait ressembler à n'importe quel éditeur sauf si vous utilisez des caractères spéciaux (avec un point de code> = 128).

Questions connexes