не могу понять эти проблемы кодирования XML
-
05-07-2019 - |
Вопрос
Следующий кусок кода (сокращенный для краткости) создает документ XML и выплевывает его в файл. Если я открою файл в Visual Studio, он будет отображаться на китайских иероглифах. Если я открою его в блокноте, он будет выглядеть как положено. Если я Console.WriteLine это выглядит правильно.
Я знаю, что это связано с кодированием, но я думал, что у меня были все утки кодирования подряд. Чего не хватает?
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());
}
Решение
Проблема в том, что вы записываете его на диск с использованием UTF-8, но он утверждает, что будет UTF-16, потому что это StringWriter
используется по умолчанию - и потому что вы явно устанавливаете для него также использование Encoding.Unicode
.
Самый простой способ исправить это - использовать StringWriter, который объявляет себя как UTF-8:
public class Utf8StringWriter : StringWriter
{
public override Encoding
{
get { return Encoding.UTF8; }
}
}
... а затем удалите строку settings.Encoding = Encoding.Unicode
. Таким образом, вы будете использовать UTF-8 повсюду. (Фактически свойство Encoding
XmlWriterSettings
игнорируется, когда вы все равно создаете XmlWriter
с TextWriter
.) р>
Если вы действительно хотите UTF-16, то при создании StreamWriter
укажите также Encoding.Unicode
. Р>
Другие советы
Я не уверен, что такое Encoding.Unicode
, но я предполагаю, что это UTF-16, который записывает в файл два байта на символ. Для обычного текста ASCII один из байтов всегда равен 0.
Попробуйте вместо этого UTF-8
. Это должно выглядеть одинаково в любом редакторе, если вы не используете специальные символы (с точкой кода > = 128).