XmlReader在序列化中的使用
和XmlDocument最大的不同——XmlReader逐行读取。单独很少使用,一般配合序列化(反序列化)使用,以下给出具体例子:
namespace ConsoleApplication1 { public class CData : IXmlSerializable { private string cDataValue = null; public string CDataValue { get { return cDataValue; } private set { cDataValue = value; } } public CData() { } public CData(string dataValue) { cDataValue = dataValue; } #region IXmlSerializable Members public System.Xml.Schema.XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { //当前读到此处的时候, //就是CData整个字符串<Name><![CData....]></Name>一堆东西 //因此Read先读取Name,然后直接用Value获取内部的XmlCData的真实数据 if (reader.Read()) { cDataValue = reader.Value; } } public void WriteXml(XmlWriter writer) { //把当前的数据转换成CDataSection写入 writer.WriteCData(cDataValue); } #endregion } // 把A改成Root [XmlRoot(ElementName = "Root")] public class A { public int Id { get; set; } //强制指定自定义的格式化方式 [XmlElement("Name", typeof(CData))] public CData Name { get; set; } } public class Program { static void Main(string[] args) { StringBuilder sbu = new StringBuilder(); //设置表头(设置编码格式和子Element的缩进符号) XmlWriterSettings setting = new XmlWriterSettings(); setting.Indent = true; setting.IndentChars = "\t"; setting.NewLineChars = "\r\n"; //必须用这种方式指定UTF-8输出格式,否则前面会加BOM, //另外注意,其实现在编码仍然是UTF-16,那是因为没有用Stream类 //而是用StringBuilder,StringBuilder默认覆盖了Stream的UTF-8编码 //强制使用UTF-16导致(具体参考:http://blog.csdn.net/ding544935/article/details/7610958) setting.Encoding = new UTF8Encoding(false); using (var writer = XmlWriter.Create(sbu, setting)) { XmlSerializer xz = new XmlSerializer(typeof(A)); //去除命名空间 XmlSerializerNamespaces emptyNameSpace = new XmlSerializerNamespaces(); emptyNameSpace.Add(string.Empty, string.Empty); //序列化 xz.Serialize(writer, new A { Id = 1, Name = new CData("董玮") }, emptyNameSpace); } Console.WriteLine(sbu.ToString()); //以下是反序列化 StringReader sr = new StringReader(sbu.ToString()); XmlReaderSettings rset = new XmlReaderSettings(); rset.IgnoreWhitespace = true; using (var reader = XmlReader.Create(sr, rset)) { A a = null; XmlSerializer xz2 = new XmlSerializer(typeof(A)); a = (A)xz2.Deserialize(reader); Console.WriteLine(a.Name.CDataValue); } } } }