请看下面这段代码:
using (StringWriter sr = new StringWriter())
{
XmlWriterSettings st = new XmlWriterSettings();
st.Encoding = Encoding.UTF8; //这里的设置将不会起作用
XmlWriter xw = XmlWriter.Create(sr, st);
DataTable _dt = ds.Tables[0];
XmlDocument xml = new XmlDocument();
XmlNode root = xml.CreateElement(ds.DataSetName);
XmlNode nodecollect = null;
if (_dt.Rows.Count > 0)
{
nodecollect = xml.CreateElement(new StringBuilder(_dt.TableName).Append("s").ToString());
XmlAttribute attr = xml.CreateAttribute("list");
attr.Value = "true";
nodecollect.Attributes.Append((XmlAttribute)attr);
root.AppendChild(nodecollect);
}
foreach (DataRow _row in _dt.Rows)
{
XmlNode newnode = xml.CreateElement(_dt.TableName);
for (int i = 0; i < _dt.Columns.Count; i++)
{
XmlNode item = xml.CreateElement(_dt.Columns[i].ColumnName);
item.InnerText = _row[i].ToString();
newnode.AppendChild(item);
}
nodecollect.AppendChild(newnode);
}
xml.AppendChild(root);
xml.Save(xw);
return sr.ToString();
}
那么sr输出的字符串中xml的编码是什么?
实际的输出结果是:utf-16;
那么为什么我在XmlWriterSetting中已经设置uft-8,而输出的依然是utf-16呢?
答案如下:
参看:http://msdn.microsoft.com/zh-cn/library/system.xml.xmlwritersettings.encoding.aspx
Encoding 属性仅应用于使用指定 Stream 或者指定文件名创建的 XmlWriter 实例。如果使用指定的 TextWriter 创建 XmlWriter 实例,则 Encoding 属性通过对基础 TextWriter的编码来重写。例如,如果将特定 XmlWriter 的这一属性设置为 Unicode (UTF-16),但基础编写器是一个编码设置为 UTF8 的 StreamWriter(源自 TextWriter),则输出将经过 UTF8 编码。
=============
因为我们在上面的代码中用到的StringWriter类,它继承自TextWriter,并且StringWriter的Encoding属性实现为Encoding.Unicode(也就是utf-16),所以按照上面的说法,StringWriter作为基础编写器将会覆盖XmlWriter的Encoding属性,所以我们在最终输出的字符串中看到的编码是utf-16而不是utf-8.
那么我们如何在输出的字符串中可以按照自己在XmlWriter中的Encoding属性指定的来输出呢?
答案如下:(我自己的想法)
using( MemoryStream s = new MemoryStream())
{
XmlWriterSettings st = new XmlWriterSettings();
st.Encoding = Encoding.Unicode;
//st.Encoding = Encoding.UTF8;
//XmlWriter xw = XmlWriter.Create(sr, st);
XmlWriter xw = XmlWriter.Create(s, st);
DataTable _dt = ds.Tables[0];
XmlDocument xml = new XmlDocument();
XmlNode root = xml.CreateElement(ds.DataSetName);
XmlNode nodecollect = null;
if (_dt.Rows.Count > 0)
{
nodecollect = xml.CreateElement(new StringBuilder(_dt.TableName).Append("s").ToString());
XmlAttribute attr = xml.CreateAttribute("list");
attr.Value = "true";
nodecollect.Attributes.Append((XmlAttribute)attr);
root.AppendChild(nodecollect);
}
foreach (DataRow _row in _dt.Rows)
{
XmlNode newnode = xml.CreateElement(_dt.TableName);
for (int i = 0; i < _dt.Columns.Count; i++)
{
XmlNode item = xml.CreateElement(_dt.Columns[i].ColumnName);
item.InnerText = _row[i].ToString();
newnode.AppendChild(item);
}
nodecollect.AppendChild(newnode);
}
xml.AppendChild(root);
xml.Save(xw);
return System.Text.Encoding.Unicode.GetString(s.ToArray());
//return System.Text.Encoding.UTF8.GetString(s.ToArray());
//return sr.ToString();
}
将上面的代码修改三处:
(1)基础编辑器改为不是派生自TextWriter的MemoryStream;(这样就不会有Encoding的干扰)
(2)在原有的XmlWriter的Setting处设置成自己想要的编码格式;
(3)返回字符串时,用对的编码对字节转化为字符串。