Проблемы с кодировкой XmlWriter - PullRequest
6 голосов
/ 14 мая 2009

У меня есть следующий код:

    MemoryStream ms = new MemoryStream();
    XmlWriter w = XmlWriter.Create(ms);

    w.WriteStartDocument(true);
    w.WriteStartElement("data");

    w.WriteElementString("child", "myvalue");

    w.WriteEndElement();//data
    w.Close();
    ms.Close();

    string test = UTF8Encoding.UTF8.GetString(ms.ToArray());

XML генерируется правильно; однако моя проблема в том, что первый символ строки 'test' - это (char # 239), что делает его недействительным для некоторых xml-анализаторов: откуда это берется? Что именно я делаю неправильно?

Я знаю, что могу решить проблему, просто начав после первого символа, но я бы лучше знал, почему она существует, чем просто исправляя проблему.

Спасибо!

Ответы [ 5 ]

13 голосов
/ 14 мая 2009

Нашел одно решение здесь: http://www.timvw.be/generating-utf-8-with-systemxmlxmlwriter/

Мне не хватало этого сверху:

XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Encoding = new UTF8Encoding(false);
MemoryStream ms = new MemoryStream();
XmlWriter w = XmlWriter.Create(ms, xmlWriterSettings);

Спасибо за помощь всем!

2 голосов
/ 14 мая 2009

Проблема в том, что ваш XML, сгенерированный записывающим устройством, имеет формат UTF-16, а вы используете UTF-8 для преобразования его в строку. Попробуйте вместо этого:

StringBuilder sb = new StringBuilder();
using (StringWriter writer = new StringWriter(sb))
using (XmlWriter w = XmlWriter.Create(writer))
{
    w.WriteStartDocument(true);
    w.WriteStartElement("data");

    w.WriteElementString("child", "myvalue");

    w.WriteEndElement();//data
}

string test = sb.ToString();
1 голос
/ 14 мая 2009
0 голосов
/ 02 июня 2009

Все они немного отключены, если вы заботитесь о метке порядка байтов, которую используют редакторы (например, Visual Studio обнаруживает кодированный в кодировке UTF8 XML и правильно выделяет синтаксис).

Вот решение:

MemoryStream stream = new MemoryStream();

XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
settings.IndentChars = "\t";

using (XmlWriter writer = XmlWriter.Create(stream, settings))
{
    // ... write

    // Make sure you flush or you only get half the text
    writer.Flush();

    // Use a StreamReader to get the byte order correct
    StreamReader reader = new StreamReader(stream,Encoding.UTF8,true);
    stream.Seek(0, SeekOrigin.Begin);
    result = reader.ReadToEnd();
}

У меня есть 2 фрагмента полностью здесь

0 голосов
/ 14 мая 2009

Вы можете изменить кодировки следующим образом:

w.Settings.Encoding = Encoding.UTF8;
...