我想将 XmlDocument
对象的 xml 发送到 HTTP 客户端,但我担心 suggested soltuion 可能不遵守 Response
已设置为使用的编码:
public void ProcessRequest(HttpContext context)
{
XmlDocument doc = GetXmlToShow(context);
context.Response.ContentType = "text/xml";
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetAllowResponseInBrowserHistory(true);
doc.Save(context.Response.OutputStream);
}
如果我将编码更改为其他内容,例如 Unicode 会怎样:
public void ProcessRequest(HttpContext context)
{
XmlDocument doc = GetXmlToShow(context);
context.Response.ContentType = "text/xml";
context.Response.ContentEncoding = System.Text.Encoding.Unicode;
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetAllowResponseInBrowserHistory(true);
doc.Save(context.Response.OutputStream);
}
Response.OutputStream
是否会即时转换写入其中的二进制数据,并使其成为 Unicode?或者
Response.ContentEncoding
只是提供信息?如果 ContentEncoding 只是提供信息,后面的文本字符串将返回什么内容编码?
context.Response.ContentEncoding = System.Text.Encoding.Unicode;
context.Response.Write("Hello World");
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.Write("Hello World");
context.Response.ContentEncoding = System.Text.Encoding.UTF16;
context.Response.Write("Hello World");
context.Response.ContentEncoding = System.Text.Encoding.ASCII;
context.Response.Write("Hello World");
context.Response.ContentEncoding = System.Text.Encoding.BigEndianUnicode;
context.Response.Write("Hello World");
最佳答案
我找到了。
答案是否定的:XmlDocument 不会遵守它写入的响应流的 ContentEncoding。
更新:正确的方法
Response.Output
和 而不是 Response.OutputStream
。两者都是流,但
Output
是 TextWriter
。当
XmlDocument
将自身保存到 TextWriter
时,它将使用编码由
TextWriter
指定。 XmlDocument
将自动更改任何xml 声明节点,即:
匹配
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 声明节点 中指定的编码。例如。:
<?xml version="1.0" encoding="UTF-8"?>
如果在 xml 声明中指定了“UTF-8”编码,则 Save(stream) 将使用 UTF-8 编码。
如果没有指定编码,例如:
<?xml version="1.0"?>
或者完全省略 xml 声明节点,则 XmlDocument 将默认为 UTF-8 unicode 编码。 ( Reference )
If an encoding attribute is not included, UTF-8 encoding is assumed when the document is written or saved out.
您也可以在 xml 声明中使用的 Some common encodings strings 是:
注意 :编码属性不区分大小写:
Unlike most XML attributes, encoding attribute values are not case-sensitive. This is because encoding character names follow ISO and Internet Assigned Numbers Authority (IANA) standards.
如果从字符串或文件加载 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 声明没有 encoding 属性,则保存的文档也不会有一个。
注意:如果 XmlDocument 正在保存到 TextWriter,则将使用的编码取自 TextWriter 对象。此外,当内容写入 TextWriter 时,xml 声明节点编码属性(如果存在)将替换为 TextWriter 的编码。 ( Reference )
The encoding on the TextWriter determines the encoding that is written out (The encoding of the XmlDeclaration node is replaced by the encoding of the TextWriter). If there was no encoding specified on the TextWriter, the XmlDocument is saved without an encoding attribute.
如果保存为字符串,则使用的编码由 xml 声明节点的编码属性(如果存在)确定。
在我的具体示例中,我通过 ASP.NET 写回 Http 客户端。我想将 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>
关于ASP.NET:将 XmlDocument 保存到 Response.OutputStream 会遵守编码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/546994/