我有一个创建一些XmlDocument的函数:
public string CreateOutputXmlString(ICollectionfields) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.Encoding = Encoding.GetEncoding("windows-1250"); StringBuilder builder = new StringBuilder(); XmlWriter writer = XmlWriter.Create(builder, settings); writer.WriteStartDocument(); writer.WriteStartElement("data"); foreach (Field field in fields) { writer.WriteStartElement("item"); writer.WriteAttributeString("name", field.Id); writer.WriteAttributeString("value", field.Value); writer.WriteEndElement(); } writer.WriteEndElement(); writer.Flush(); writer.Close(); return builder.ToString(); }
我设置了一个编码,但在我创建XmlWriter后,它确实有utf-16编码.我知道这是因为字符串(和我猜想的StringBuilder)是用utf-16编码的,你无法改变它.
那么如何在编码属性设置为"windows-1250"的情况下轻松创建此xml?它甚至不必在这种编码中编码,它只需具有指定的属性.
编辑:它必须在.Net 2.0中,因此不能使用任何新的框架元素.
您需要使用具有适当编码的StringWriter.不幸的是StringWriter不允许你直接指定编码,所以你需要一个这样的类:
public sealed class StringWriterWithEncoding : StringWriter { private readonly Encoding encoding; public StringWriterWithEncoding (Encoding encoding) { this.encoding = encoding; } public override Encoding Encoding { get { return encoding; } } }
(这个问题类似但不完全重复.)
编辑:回答评论:将StringWriterWithEncoding传递给XmlWriter.Create而不是StringBuilder,然后在最后调用ToString().
只是为什么会这样做的一些额外的解释.
字符串是字符序列,而不是字节.字符串本身不是"编码"的,因为它们使用的字符存储为Unicode代码点.编码不会在字符串级别进行SENSE.
编码是从一系列代码点(字符)到字节序列的映射(用于存储在基于字节的系统(如文件系统或内存)上).该框架不允许您指定编码,除非有令人信服的理由,比如使16位代码点适合基于字节的存储.
因此,当您尝试将XML编写到StringBuilder中时,实际上是在构建XML字符序列并将其作为字符序列写入,因此不执行编码.因此,没有编码字段.
如果要使用编码,XmlWriter必须写入Stream.
关于你在MemoryStream中找到的解决方案,没有任何违法行为,但它只是在手臂上移动并移动热空气.您使用'windows-1252'对代码点进行编码,然后将其解析回代码点.唯一可能发生的变化是未在windows-1252中定义的字符转换为'?' 这个过程中的人物.
对我来说,正确的解决方案可能是以下方案.根据您的函数用途,您可以将Stream作为参数传递给函数,以便调用者决定是将其写入内存还是文件.所以它会写成这样:
public static void WriteFieldsAsXmlDocument(ICollection fields, Stream outStream) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.Encoding = Encoding.GetEncoding("windows-1250"); using(XmlWriter writer = XmlWriter.Create(outStream, settings)) { writer.WriteStartDocument(); writer.WriteStartElement("data"); foreach (Field field in fields) { writer.WriteStartElement("item"); writer.WriteAttributeString("name", field.Id); writer.WriteAttributeString("value", field.Value); writer.WriteEndElement(); } writer.WriteEndElement(); } }
MemoryStream memoryStream = new MemoryStream(); XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.Encoding = Encoding.UTF8; XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings); xmlWriter.WriteStartDocument(); xmlWriter.WriteStartElement("root", "http://www.timvw.be/ns"); xmlWriter.WriteEndElement(); xmlWriter.WriteEndDocument(); xmlWriter.Flush(); xmlWriter.Close(); string xmlString = Encoding.UTF8.GetString(memoryStream.ToArray());
从这里