Почему у меня ATOM XML UTF-16, а не UTF-8 - PullRequest
1 голос
/ 15 июля 2009

У меня есть этот код для создания канала ATOM

Dim xmlResult As New StringBuilder
Dim settings As New XmlWriterSettings
Dim atomWriter As XmlWriter = XmlWriter.Create(xmlResult, settings)
Dim atomFormatter As Atom10FeedFormatter = New Atom10FeedFormatter(feed)
atomFormatter.WriteTo(atomWriter)
atomWriter.Close()

Возвращает XML, который начинается так:

<?xml version="1.0" encoding="utf-16"?><feed xmlns="http://www.w3.org/2005/Atom">

Что бы я ни пытался, я не могу заставить его вернуть utf-8 вместо utf-16. Когда это utf-16, он не работает с IE8, но utf-8 работает нормально. Откуда я знаю, что это работает? Хорошо, я слышу, как вы спрашиваете, не могу ли я получить его, чтобы он возвращал utf-8, и в итоге я использую эту строку кода, чтобы вернуть канал в браузер:

Response.Write(Replace(xmlResult.ToString, "utf-16", "utf-8"))

Это, безусловно, худший взлом, который ты видел сегодня, если не жалко тебя!

Итак, вот что я пытался получить UTF-8:

Response.ContentEncoding = System.Text.Encoding.UTF8
Response.Charset = "UTF-8"
settings.Encoding = System.Text.Encoding.UTF8

Строка настроек - это то, что я думал, что будет работать, но не для меня. Насколько я понимаю, XML Writer - это та часть, которая добавляет декларацию XML, но в качестве настроек. Кодирование не работает, я в тупике. Пожалуйста, помогите!

Спасибо

Ответы [ 2 ]

2 голосов
/ 04 ноября 2009

Основная причина заключается в том, что при вызове XmlWriter.Create с помощью StringBuilder он создает новый экземпляр StringWriter, который всегда имеет кодировку UTF-16, и создает XmlWriter вокруг этого StringWriter. Глядя в Reflector, похоже, что кодировка StringWriter является закрытой статической переменной, поэтому все экземпляры StringWriter будут иметь одинаковую кодировку.

По какой причине вы не создаете XmlWriter, который напрямую записывает в Response OutputStream?

Если вы можете сделать это, этот код работает для меня:

With Response
  .ContentEncoding = Encoding.UTF8
  .ContentType = "text/xml"
End With

Dim atomFormatter As Atom10FeedFormatter = New Atom10FeedFormatter(feed)
Dim settings As XmlWriterSettings = New XmlWriterSettings

With settings
  .OmitXmlDeclaration = False
  .Encoding = Encoding.UTF8
End With

Using atomWriter As XmlWriter = XmlWriter.Create(Response.OutputStream, settings)
  atomFormatter.WriteTo(atomWriter)
  atomWriter.Close()
End Using

Response.End()

Если вам нужно использовать StringBuilder по уважительной причине, возможно, вы могли бы подумать о том, чтобы пропустить декларацию Xml и добавить ее в свой код перед вызовом atomFormatter.WriteTo. В качестве альтернативы вы можете написать свою функцию для принятия произвольного потока и создать для нее XmlWriter, используя MemoryStream или FileStream, когда вы не планируете писать напрямую в Response.OutputStream.

Извинения, если код не идиоматический VB; Я в основном пишу на C #.

0 голосов
/ 15 июля 2009

Попробуйте "settings.Encoding = System.Text.Encoding.UTF8"

Я попробовал и, как заметил MrBrutal, он не работает.

Полагаю, поскольку строка в .NET всегда UTF-16, запись XML в строку всегда приводит к кодировке utf-16, несмотря ни на что.

Вы должны попробовать записать в поток, где у вас больше контроля. Если цель состоит в том, чтобы записать в файл, то поток должен быть подключен к нему и записывать непосредственно туда.

Если запись в файл не является конечной целью, то что это? Может немного помочь, если вы немного объясните вариант использования. Возможно, конечный результат принадлежит байтовому массиву, а не строке.

...