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);
            }
        }
    }
}
时间: 2024-08-02 12:22:14

XmlReader在序列化中的使用的相关文章

Java序列化中的SerialVersionUid

版权声明:本文为博主fbysss原创文章,转载请注明出处 作者:fbysssmsn:jameslast[email protected]  blog:blog.csdn.NET/fbysss声明:本文由fbysss原创,转载请注明出处关键字:SerialVersionUid 序列化 一.前言 SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容.如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassExceptio

【Java】对象序列化中出现的java.io.StreamCorruptedException异常

今天在试验对象序列化,看到在类继承了Serializable接口,还有两个函数会在对象序列化及反序列化时默认自动执行,分别是writeObject和readObject. 进行了简单的试验,发现在在程序执行过程中出现了下述异常: java.io.StreamCorruptedException: invalid type code: 00 at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1520) at java

序列化中serialVersionUID的作用

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常.(InvalidCastException) serialVersionUID有两种显示的生成方式: 一个是默认的1L,比如:private static final long

(七)实体json序列化中的JsonIgnore

在spring boot项目中已经包含有json序列化的框架,具体在包com.fasterxml.jackson.annotation中,建议看看详细源码. 但在项目应用上还是会有一些坑会出现的,举个例子: 在一个复杂的业务模型中包含有200个字段,在查询列表时只查询其中某20个字段,在查询详情中需要把所有字段都查询出来. 一般情况下,如果是开始做一个新功能,那么我们的设计应该类似是这样的: model ---- QueryModel ,包含20个字段,响应查询列表结果 ---- DetailM

Python序列化中json模块和pickle模块

1.什么是序列化? 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化. 比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给? 现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来. 但是我们都知道,对于文件来说是没有字典这个概念的,所以我们只能将数据转换成字典放到文件中. 你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢? 没错序列化的过程就是从dic 变成str(dic)

关于java序列化中的一个细节

java序列化机制的可以参考很多资料了,最近在看的时候发现了一些问题. 1. 默认的序列化机制,很多书里讲到序列化类只序列化类名,实例变量,不会实例化类变量(static)和瞬态变量(transient). 我使用1.6,1.7,1.8测试了一下,static都是可以被序列化的. 测试代码: 1 public class Logg implements Serializable{ 2 3 private static String name; 4 private transient String

字符串系列函数在序列化中的问题

最近用到了protobuf传输数据,但在protobuf之前还有个协议头. 因为是重构,所以需要模拟协议头部.有如下代码 string data; char buffer[256]; memcpy(buffer, &header, sizeof(header)); data.append(buffer); client端发给server端的数据,总是少几个字节,用gdb调试时,发现有部分截断. 经过定位,发现是buffer序列成为二进制后,有Cstring的终止字符.导致append 不完全.

对象序列化中transient关键字的用途

对象序列化中 子类和父类构造函数的调用问题

第三种情况: