我找到了。
答案是否定的:XmlDocument 不会遵守它正在写入的响应流的 ContentEncoding。
更新:正确的做法
-
使用Response.Output,不使用 Response.OutputStream。
两者都是流,但Output 是TextWriter。
当XmlDocument 将自己保存到TextWriter 时,它将使用编码
由TextWriter 指定。 XmlDocument 将自动更改任何
xml声明节点,即:
匹配Response.Output的编码设置所使用的编码。
Response.OutputTextWriter 的编码设置来自
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 声明节点 中指定的编码。例如:
<?xml version="1.0" encoding="UTF-8"?>
如果在 xml 声明中指定了“UTF-8”编码,那么 Save(stream) 将使用 UTF-8 编码。
如果 no 指定编码,例如:
<?xml version="1.0"?>
或完全省略xml声明节点,则XmlDocument将默认为UTF-8 unicode编码。 (Reference)
如果编码属性不是
包括在内,假定为 UTF-8 编码
写入或保存文档时
出去。
Some common encodings strings,您也可以在 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
- EUC-JP
注意:编码属性不区分大小写:
与大多数 XML 属性不同,编码
属性值不是
区分大小写。这是因为
编码字符名称遵循 ISO
和互联网分配号码
权威 (IANA) 标准。
如果您从字符串或文件加载 XML,并且它不包含 xml 声明节点,您可以 manually add one to the 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 对象。此外,当内容写入 TextWriter 时,xml 声明节点编码属性(如果存在)将替换为 TextWriter 的编码。 (Reference)
TextWriter 上的编码
确定编码是
写出(的编码
XmlDeclaration 节点被替换为
TextWriter 的编码)。如果有
没有指定编码
TextWriter,XmlDocument 被保存
没有编码属性。
如果保存为字符串,则使用的编码由 xml 声明节点的编码属性(如果存在)确定。
在我的具体示例中,我正在通过 ASP.NET 写回 Http 客户端。我想将 Response.Encoding 类型设置为适当的值 - 我需要匹配 XML 本身将包含的内容。
执行此操作的适当方法是将 xml 保存到 Response.Output,而不是 Response.OutputStream。 Response.Output 是一个 TextWriter,其 Encoding 值遵循您为 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>