C# 中xml数组的序列和反序列化方法

2023-05-16

先来看xml

复制代码


<?xml version='1.0'?>
<root xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
  <Person>
    <Name>小莫</Name>
    <Age>20</Age>
    <Books>
      <Book>
        <Title>马列主义</Title>
        <ISBN>SOD1323DS</ISBN>
      </Book>
      <Book>
        <Title>高等数学</Title>
        <ISBN>SOD1S8374</ISBN>
      </Book>
    </Books>
  </Person>
  <Person>
    <Name>小红</Name>
    <Age>20</Age>
    <Books>
      <Book>
        <Title>思想</Title>
        <ISBN>SID1323D845</ISBN>
      </Book>
    </Books>
  </Person>
</root>  

复制代码

 

这个xml包含多个Person对象,每个Person对象又包含一个Books对象和多个book对象,反序列化XML时关键是看怎么理解xml的结构,理解正确了就很好构造对应的类,理解错了可能就陷入坑里。

首先root是整个文件的根节点,它是由多个Person组成的。

复制代码

复制代码


[System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("root", IsNullable = false)]
    public class BaseInfo
    {
        [System.Xml.Serialization.XmlElementAttribute("Person")]
        public List<Person> PersonList { get; set; }
    }  

复制代码

复制代码

再看Person对象,Person是由name和age两个属性和一个Books对象组成,Person可以定义成

复制代码

复制代码


[System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("Person", IsNullable = false)]
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        [System.Xml.Serialization.XmlElementAttribute("Books")]
        public Books Books { get; set; }
    }  

复制代码

复制代码

这里理解的关键是把下面这小段xml理解成一个包含多个Book的对象,而不是把它理解成book的数组

复制代码

复制代码


    <Books>
      <Book>
        <Title>毛泽思想</Title>
        <ISBN>SID1323DSD</ISBN>
      </Book>
    </Books>  

复制代码

复制代码

如果把她理解成一个数据就容易把Person定义成

复制代码

复制代码


[System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("Person", IsNullable = false)]
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        [System.Xml.Serialization.XmlElementAttribute("Books")]
        public List<Book> Books { get; set; }
    }  

复制代码

复制代码

而book的定义如下

复制代码

复制代码


   [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("Book", IsNullable = false)]
    public class Book
    {
        public string Title { get; set; }
        public string ISBN { get; set; }
    }  

复制代码

复制代码

序列化生成的xml不包含Book节点


,生成的xml如下  

复制代码

复制代码


<?xml version="1.0"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Person>
    <Name>小莫</Name>
    <Age>20</Age>
    <Books>
      
        <Title>马列主义</Title>
        <ISBN>SOD1323DS</ISBN>
      
    </Books>
  </Person>
  <Person>
    <Name>小红</Name>
    <Age>20</Age>
    <Books>
        <Title>毛泽思想</Title>
        <ISBN>SID1323DSD</ISBN>
      
    </Books>
  </Person>
</root>  

复制代码

复制代码

 

之所以出现上面的情况是因为:


public List<Book> Books { get; set; }
和Book同属一个节点层次,在List<Book> Books上显式指定了属性名称Books,那么这个节点就是Books,跟Book上定义指定的[System.Xml.Serialization.XmlRootAttribute("Book", IsNullable = false)]
没有关系,它是用来指示Book是跟节点时的名称。
或者可以这样理解xml是由多个节点组成的,而Book类定义不是一个节点,它只是一个定义,要想xml中出现book,就需要再加一个节点,我们把Person节点加到Books对象中

  

复制代码

复制代码


    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public class Books
    {
        [System.Xml.Serialization.XmlElementAttribute("Book")]
        public List<Book> BookList { get; set; }
    }  

复制代码

复制代码

这样就多出了一个节点,再结合刚开始的person定义就能序列化出正确的xml了

完整的代码

复制代码

复制代码


 [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("root", IsNullable = false)]
    public class BaseInfo
    {
        [System.Xml.Serialization.XmlElementAttribute("Person")]
        public List<Person> PersonList { get; set; }
    }

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("Person", IsNullable = false)]
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        [System.Xml.Serialization.XmlElementAttribute("Books")]
        public Books Books { get; set; }
    }

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public class Books
    {
        [System.Xml.Serialization.XmlElementAttribute("Book")]
        public List<Book> BookList { get; set; }
    }

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("Book", IsNullable = false)]
    public class Book
    {
        public string Title { get; set; }
        public string ISBN { get; set; }
    }  

复制代码

复制代码

复制代码

复制代码


 static void Main(string[] args)
        {


            BaseInfo baseInfo = new BaseInfo();
            List<Person> personList = new List<Person>();
            Person p1 = new Person();
            p1.Name = "小莫";
            p1.Age = 20;

            List<Book> books = new List<Book>();
            Book book = new Book();
            book.Title = "马列主义";
            book.ISBN = "SOD1323DS";
            books.Add(book);
            p1.Books = new Books();
            p1.Books.BookList = books;

            Person p2 = new Person();
            p2.Name = "小红";
            p2.Age = 20;

            List<Book> books2 = new List<Book>();
            Book book2 = new Book();
            book2.Title = "毛泽思想";
            book2.ISBN = "SID1323DSD";
            books2.Add(book2);
            p2.Books =new Books();
            p2.Books.BookList = books2;

            personList.Add(p1);
            personList.Add(p2);
          
                     
            baseInfo.PersonList = personList;

            string postXml2 = SerializeHelper.Serialize(typeof(BaseInfo), baseInfo);
            Console.ReadLine();
        }
       
    }  

复制代码

复制代码

序列化用到的类

复制代码

复制代码


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace ConsoleApplication1
{
    public class SerializeHelper
    {
        public static string Serialize(Type type, object o)
        {
            string result = string.Empty;
            try
            {
                XmlSerializer xs = new XmlSerializer(type);
                MemoryStream ms = new MemoryStream();
                xs.Serialize(ms, o);
                ms.Seek(0, SeekOrigin.Begin);
                StreamReader sr = new StreamReader(ms);
                result = sr.ReadToEnd();
                ms.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("对象序列化成xml时发生错误:" + ex.Message);
            }
            return result;
        }

        /// <summary>
        /// 序列化XML时不带默认的命名空间xmlns
        /// </summary>
        /// <param name="type"></param>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string SerializeNoneNamespaces(Type type, object o)
        {
            string result = string.Empty;
            try
            {
                XmlSerializer xs = new XmlSerializer(type);
                MemoryStream ms = new MemoryStream();
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");//Add an empty namespace and empty value
                xs.Serialize(ms, o, ns);
                ms.Seek(0, SeekOrigin.Begin);
                StreamReader sr = new StreamReader(ms);
                result = sr.ReadToEnd();
                ms.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("对象序列化成xml时发生错误:" + ex.Message);
            }
            return result;
        }

        /// <summary>
        /// 序列化时不生成XML声明和XML命名空间
        /// </summary>
        /// <param name="type"></param>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string SerializeNoNamespacesNoXmlDeclaration(Type type, object o)
        {
            string result = string.Empty;
            try
            {
                XmlSerializer xs = new XmlSerializer(type);
                MemoryStream ms = new MemoryStream();
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

                XmlWriterSettings settings = new XmlWriterSettings();
                settings.OmitXmlDeclaration = true;//不编写XML声明
                XmlWriter xmlWriter = XmlWriter.Create(ms, settings);

                ns.Add("", "");//Add an empty namespace and empty value
                xs.Serialize(xmlWriter, o, ns);
                ms.Seek(0, SeekOrigin.Begin);
                StreamReader sr = new StreamReader(ms);
                result = sr.ReadToEnd();
                ms.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("对象序列化成xml时发生错误:" + ex.Message);
            }
            return result;
        }

        public static object Deserialize(Type type, string xml)
        {
            object root = new object();
            try
            {
                XmlSerializer xs = new XmlSerializer(type);
                MemoryStream ms = new MemoryStream();
                StreamWriter sw = new StreamWriter(ms);
                sw.Write(xml);
                sw.Flush();
                ms.Seek(0, SeekOrigin.Begin);
                root = xs.Deserialize(ms);
                ms.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("xml转换成对象时发生错误:" + ex.Message);
            }
            return root;
        }
    }
}  

复制代码

复制代码


再看一个例子,简单数组类型的序列化
  

复制代码

复制代码


<?xml version="1.0"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <barcodes>
    <barcode>AAA</barcode>
    <barcode>BBB</barcode>
  </barcodes>
</root>  

复制代码

复制代码

我们经常搞半天不知道要怎么书写上面xml对应的类,总是容易出现上面说过的错误,关键还是看怎么理解barcodes,和上面的例子类似,这里只写类怎么创建

复制代码

复制代码


  [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("root", IsNullable = false)]
    public class DownLoadPDFRequest
    {
        
        [System.Xml.Serialization.XmlElementAttribute("barcodes")]
        public barcoders barcodes { get; set; }
    }

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    //[System.Xml.Serialization.XmlRootAttribute("barcoders", IsNullable = false)]
    public class barcoders
    {
        private List<string> _barcode;

        [System.Xml.Serialization.XmlElementAttribute("barcode")]
        public List<string> BarCode
        {
            get { return _barcode; }
            set { _barcode = value; }
        }

    }  

复制代码

复制代码

复制代码

复制代码


 static void Main(string[] args)
        {


            DownLoadPDFRequest request = new DownLoadPDFRequest();

            List<barcoders> barcodes = new List<barcoders>();

            List<string> bars=new List<string>();
            bars.Add("AAA");
            bars.Add("BBB");
            request.barcodes = new barcoders();;
            request.barcodes.BarCode = bars;


            string postXml = SerializeHelper.Serialize(typeof(DownLoadPDFRequest), request);
}  

复制代码

复制代码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中xml数组的序列和反序列化方法 的相关文章

随机推荐

  • 对线程与进程的区别以及对多线程并发的理解

    一 线程与进程的区别 先简单说说线程与进程的概念 xff1a xff08 1 xff09 进程是指一个内存中运行的应用程序 xff0c 比如在Windows系统中 xff0c 一个运行的exe就是一个进程 xff08 2 xff09 线程是
  • 单片机学习经验总结

    单片机的学习是嵌入式中的裸机开发 xff0c 也就是不基于操作系统的开发过程 xff0c 你只要把自己学的程序下载到单片机内执行即可 xff08 这个过程有个专业术语 xff1a 烧写 xff09 在这个过程中 xff0c 你所写的程序 x
  • 三极管的工作原理(详细、通俗易懂、图文并茂)

    一 很多初学者都会认为三极管是两个 PN 结的简单凑合 xff08 如图1 xff09 这种想法是错误的 xff0c 两个二极管的组合不能形成一个三极管 我们以 NPN 型三极管为例 xff08 见图 2 xff09 xff0c 两个 PN
  • 三极管工作原理图解,快速了解三极管结构和工作原理

    了解三极管工作原理前 xff0c 先看一张三极管内部结构原理图 xff1b 从图中可以清晰的看出NPN和PNP内部结构的区别 三极管NPN型和PNP型的工作原理 xff1a NPN三极管 xff1a Vb lt Ve xff08 截止状态
  • C# 获取进程或线程的信息

    using System using System Collections Generic using System Linq using System Text using System Diagnostics namespace Con
  • C#图片保存与读取,以及图片另存操作

    照片的保存与读取 lt summary gt 图片转二进制 lt summary gt lt param name 61 34 imgPhoto 34 gt 图片对象 lt param gt lt returns gt 二进制 lt ret
  • C#异常解决:在调用OLE之前,必须将当前线程设置为单线程单单元(STA)模式。

    问题来源 xff1a 昨晚上在调试数据库大作业的时候 xff0c 我在注册界面Register里点击 34 上传头像 34 这个linklabel时 xff0c 程序出现了一个异常 xff1a 在调用OLE之前 xff0c 必须将当前线程设
  • Qt调用OpenCV汇总(1)

    1 在Qt Creator上新建一个项目 右键新项目 gt gt 添加库 gt gt 外部库 gt gt 选中库文件路径 gt gt 下一步 xff0c 完成 xff0c 添加到 pro文件中 然后再在pro文件中手动输入下面代码 xff1
  • qt调用opencv汇总(2)

    OpenCV3 4 3 43 Qt5 9 4 QtCreator 开发环境搭建 之前有过对OpenCV3 4 2 43 VS2015编译及环境搭建 xff0c 今天使用OpenCV3 4 3 43 QtCreator5 9 4编译及环境搭建
  • 关于QT下配置OpenCV3.4.0后出现 error: undefined reference to ‘cv::xxx‘的问题及解决方案,直接使用编译好的opencv库

    按照网上的办法 xff0c 在QT中pro文件末尾添加以下代码来引入OpenCV的库和头文件 xff1a INCLUDEPATH 43 61 D OpenCV3 4 opencv build mingw install x64 mingw
  • C#实现最小二乘法

    根据http zh wikipedia org wiki E6 9C 80 E5 B0 8F E4 BA 8C E4 B9 98 E6 B3 95里面的说法 xff1a 线性函数模型 典型的一类函数模型是线性函数模型 最简单的线性式是 xf
  • C++动态(显式)调用 C++ dll示例

    1 创建DLL新项目Dll1 xff0c Dll1 cpp 1 extern 34 C 34 declspec dllexport const char myfunc 2 3 return 34 hello 34 4 生成后 xff0c 将
  • 用quagga建立BGP会话

    本文将讲述使用quagga建立一个BGP会话 本次测试拓扑 假设运营商A与运营商B建立BGP对等互联来交换路由 下面是她们的AS号和IP地址范围 xff1a 运营商 A AS38372 xff0c IP段 172 16 0 0 16 xff
  • c++中堆、栈内存分配概念示例讲解

    首先来看看主要有几种程序内存分配 xff1a 一个由C C 43 43 编译程序占用内存分为以下几个部分 1 栈区 xff08 stack xff09 由编译器自动分配释放 xff0c 存放函数参数值 xff0c 局部变量值等 其操作方式类
  • winform窗体控件多,加载慢、卡顿的解决办法

    protected override CreateParams CreateParams get CreateParams cp 61 base CreateParams cp ExStyle 61 0x02000000 用双缓冲绘制窗口的
  • c# 中ToolStrip控件中button控件,显示文字和图标

    1 同时显示文字和图标 DisplayStyle 属性设为 ImageAndText DisplayStyle属性用来设置图标的显示状态为 图片 文字 图片和文字 ImageRelation 属性设为 ImageBeforeText Tex
  • C#中的线程池使用方法

    1 线程池的概念 许多应用程序使用多个线程 xff0c 但这些线程经常在休眠状态中耗费大量的时间来等待事件发生 其他线程可能进入休眠状态 xff0c 并且仅定期被唤醒以轮询更改或更新状态信息 xff0c 然后再次进入休眠状态 为了简化对这些
  • C# 读写ini配置文件demo

    INI就是扩展名为 34 INI 34 的文件 其实他本身是个文本文件 可以用记事本打工 主要存放的是用户所做的选择或系统的各种参数 INI文件其实并不是普通的文本文件 它有自己的结构 由若干段落 SECTION 组成 在每个带括号的标题下
  • C#实现实体类和XML相互转换

    一 实体类转换成XML 将实体类转换成XML需要使用XmlSerializer类的Serialize方法 xff0c 将实体类序列化 public static string XmlSerialize lt T gt T obj using
  • C# 中xml数组的序列和反序列化方法

    先来看xml lt xml version 61 39 1 0 39 gt lt root xmlns xsi 61 39 http www w3 org 2001 XMLSchema instance 39 xmlns xsd 61 39