Я нашел это.
Ответ отрицательный: XmlDocument не будет учитывать ContentEncoding потока ответов, в который он записывает.
Обновление: правильный способ сделать это
Используйте Response.Output
и НЕ Response.OutputStream
.
Оба являются потоками, но Output
является TextWriter
.
Когда XmlDocument
сохраняет себя в TextWriter
, он использует кодировку
указано TextWriter
. XmlDocument
автоматически изменит любой
узел объявления xml, т. е .:
<? Xml version = "1.0" encoding = "ISO-8859-1"?>
для соответствия кодировке, используемой настройкой кодирования Response.Output
.
Настройки кодирования Response.Output
TextWriter
получены из
Response.ContentEncoding
значение.
Используйте doc.Save
, , а не Response.Write(doc.ToString())
или Response.Write(doc.InnerXml)
Вы НЕ хотите сохранить XML в строку или вставить XML в строку,
и response.Write
это, потому что это:
- не соответствует указанной кодировке
- пустая трата памяти
Подводя итог: сохраняя в TextWriter
: узел декларации XML, содержимое XML,
и кодировка содержимого HTML-ответа будет соответствовать.
Пример кода:
public class Handler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
//Note: We add IRequiesSessionState so that we'll have access to context.Session object
//Otherwise it will be null
public void ProcessRequest(HttpContext context)
{
XmlDocument doc = GetXmlToShow(context); //GetXmlToShow will look for parameters from the context
if (doc != null)
{
context.Response.ContentType = "text/xml"; //must be 'text/xml'
context.Response.ContentEncoding = System.Text.Encoding.UTF8; //we'd like utf-8
doc.Save(context.Response.Output); //doc save itself to the textwriter, using the encoding of the text-writer (which comes from response.contentEncoding)
}
#region Notes
/*
* 1. Use Response.Output, and NOT Response.OutputStream.
* Both are streams, but Output is a TextWriter.
* When an XmlDocument saves itself to a TextWriter, it will use the encoding
* specified by the TextWriter. The XmlDocument will automatically change any
* xml declaration node, i.e.:
* <?xml version="1.0" encoding="ISO-8859-1"?>
* to match the encoding used by the Response.Output's encoding setting
* 2. The Response.Output TextWriter's encoding settings comes from the
* Response.ContentEncoding value.
* 3. Use doc.Save, not Response.Write(doc.ToString()) or Response.Write(doc.InnerXml)
* 3. You DON'T want to Save the xml to a string, or stuff the xml into a string
* and response.Write that, because that
* - doesn't follow the encoding specified
* - wastes memory
*
* To sum up: by Saving to a TextWriter: the XML Declaration node, the XML contents,
* and the HTML Response content-encoding will all match.
*/
#endregion Notes
}
public bool IsReusable { get { return false; } }
}
Кодировка, которую XmlDocument будет использовать при сохранении в поток, зависит от кодировки, указанной в узле объявления xml . e.g.:
<?xml version="1.0" encoding="UTF-8"?>
Если в объявлении xml указана кодировка "UTF-8", то Save (stream) будет использовать кодировку UTF-8 .
Если кодировка не указана , например ::1010*
<?xml version="1.0"?>
или узел объявления xml полностью пропущен, тогда по умолчанию XmlDocument будет UTF-8 кодировка в юникоде. (* * Ссылка тысяча восемьдесят пять * 1 086 *)
Если атрибут кодирования не
включено кодирование UTF-8
когда документ написан или сохранен
вне.
Некоторые общие строки кодирования , которые вы также можете использовать в объявлении xml:
- UTF-8
- UTF-16
- ISO-10646-UCS-2
- ISO-10646-UCS-4
- ISO-8859-1
- ISO-8859-2
- ISO-8859-3
- ISO-8859-4
- ISO-8859-5
- ISO-8859-6
- ISO-8859-7
- ISO-8859-8
- ISO-8859-9
- ISO-2022-JP
- Shift_JIS
Примечание : Атрибут кодирования не чувствителен к регистру:
В отличие от большинства атрибутов XML, кодировка
значения атрибута не
с учетом регистра. Это потому что
имена кодирующих символов соответствуют ISO
и интернет назначенные номера
Органы власти (IANA).
Если вы загрузили XML из строки или файла, и он не содержал узел объявления xml, вы можете добавить его вручную в XmlDocument , используя:
// Create an XML declaration.
XmlDeclaration xmldecl;
xmldecl = doc.CreateXmlDeclaration("1.0", null, null);
xmldecl.Encoding="UTF-8";
// Add the new node to the document.
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmldecl, root);
Если XmlDocument не имеет декларации xml или если декларация xml не имеет атрибута кодировки, сохраненный документ также не будет иметь его.
Примечание. Если XmlDocument сохраняется в TextWriter, то используемая кодировка берется из объекта TextWriter. Кроме того, атрибут кодировки узла объявления xml (если имеется) будет заменен кодировкой TextWriter, когда содержимое записывается в TextWriter. (* +1146 * Ссылка * * тысяча сто сорок семь)
Кодировка на TextWriter
определяет кодировку
выписан (кодировка
Узел XmlDeclaration заменяется на
кодирование TextWriter). Если там
кодировка не указана на
TextWriter, XmlDocument сохранен
без атрибута кодирования.
При сохранении в строку используемая кодировка определяется атрибутом кодировки узла декларации xml, если таковой имеется.
В моем конкретном примере я пишу обратно клиенту Http через ASP.NET. я хочу установить для типа Response.Encoding подходящее значение - и мне нужно соответствовать тому, что будет содержать сам XML.
Надлежащий способ сделать это - сохранить XML-файл в Response.Output, а не в Response.OutputStream. Response.Output является TextWriter, значение кодировки которого соответствует значению, заданному для Response.Encoding.
Другими словами:
context.Response.ContentEncoding = System.Text.Encoding.ASCII;
doc.Save(context.Response.Output);
Результаты в XML:
<?xml version="1.0" encoding="us-ascii" ?>
<foo>Hello, world!</foo>
в то время как:
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
doc.Save(context.Response.Output);
Результаты в XML:
<?xml version="1.0" encoding="utf-8" ?>
<foo>Hello, world!</foo>
и
context.Response.ContentEncoding = System.Text.Encoding.Unicode;
doc.Save(context.Response.Output);
Результаты в XML:
<?xml version="1.0" encoding="utf-16" ?>
<foo>Hello, world!</foo>