先来看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>
</Books>
</Person>
<Person>
<Name>小红</Name>
<Age>20</Age>
<Books>
<Book>
<Title>思想</Title>
<ISBN>SID1323DSD</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 = ; 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 = ; 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(, 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(, 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(, 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(, 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);
}


C# xml数组的序列和反序列化的更多相关文章

  1. .NET Core 对象到字节数组的序列化和反序列化

    .NET Core中利用MemoryStream和BinaryFormatter可以实现对象到字节数组的序列化和反序列化: 定义ObjectSerializer类,实现对象到字节数组的序列化和反序列化 ...

  2. 理解PHP数组的序列化和反序列化

    当我们想要将数组值存储到数据库时,就可以对数组进行序列化操作,然后将序列化后的值存储到数据库中.其实PHP序列化数组就是将复杂的数组数据类型转换为字符串,方便数组存库操作.对PHP数组进行序列化和反序 ...

  3. .NET(C#)使用Serialize、Deserialize序列和反序列化XML文档

    本文给大家分享一下C#操作(读取.写入)XML文档的实用方法,即用.NET本身提供的Deserialize和Serialize进行反序列化和序列化XML文档.这种方法主要是对比较规范的XML文档进行操 ...

  4. 对象序列和反序列化Xml

    1. XmlArray和XmlArrayItem XmlArray和XmlArrayItem是不同的,XmlArray是指这个数组叫什么,XmlArrayItem 值数组的每个元素叫什么. <X ...

  5. xml对象的序列化和反序列化

    对象序列化: /// <summary>        /// 将一个对象序列化为XML字符串        /// </summary>        /// <par ...

  6. json数组的序列化和反序列化json数组的序列化和反序列化

    如题,我就不多说了,自己看代码的,很好理解 using System; using System.Collections.Generic; using System.Web; using System ...

  7. XML数组和对象,反之亦然

    惊人的互相转换,还是因为麻烦.程序很反感麻烦猿 1 阵转xml <?php /* 一维数组转xml 思路: 循环数组每一个单元,添加到xml文档节点中去 */ /* $arr = array( ...

  8. POJ--3321 Apple Tree(树状数组+dfs(序列))

    Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 22613 Accepted: 6875 Descripti ...

  9. php 数组转xml 数组转json xml转数组 json转数组

    array->xml <?php function array2xml($array, $tag) { function ia2xml($array) { $xml="" ...

随机推荐

  1. Vue自用axios封装

    [本文出自天外归云的博客园] 这是我的Vue项目中的request.js文件,请求报错了看console就会有具体请求信息,方便调试.分享一下. 其中用到了axios和element-ui的组件,ax ...

  2. JVM系列——从菜鸟到入门

    持续更新系列. 参考自<深入理解Java虚拟机>.<Java性能权威指南>.<分布式Java应用基础与实践>. Java的内存结构 JVM系列——运行时数据区 JV ...

  3. Syncfusion SfDataGrid 导出Excel

    var options = new ExcelExportingOptions { ExcelVersion = ExcelVersion.Excel2013, }; //不需要导出的字段 optio ...

  4. RSA/SHA1加密和数字签名算法在开放平台中的应用

    加密算法 加密算法分为两大类:1.对称加密算法:2.非对称加密算法.   密钥个数 加密 解密 对称加密 一个 使用密钥加密 使用同一个密钥解密 非对称加密 两个,公钥和私钥 使用其中一把密钥加密 使 ...

  5. 阿里云ECS服务器无法上传文件的解决方案

    1.安装软件启动FTP服务 yum install vsftpd # 安装service vsftpd start # 启动服务chkconfig vsftpd on # 开机启动 2.防火墙ipta ...

  6. python 中 __init__方法

    注意1,__init__并不相当于C#中的构造函数,执行它的时候,实例已构造出来了. class A(object): def __init__(self,name): self.name=name ...

  7. 【Static Program Analysis - Chapter 4】格理论(Lattice Theory)与程序分析

    # 从一个例子说起, **任务:给定这样一段代码,假设我们想分析出这段代码中,每个数值型变量和表达式的符号,即正数,负数或0.** 此外,还有可能出现两种情况就是: 1.我们无法分析出结果,即我们无法 ...

  8. JS备忘

    1. Promise用法 js异步调用较多,如果某个操作是基于上个异步结果才能执行的,再有一个操作又是基于此操作的,则需要嵌套多层代码,在ES6中引入了Promise写法,可以比较优雅的解决这个问题: ...

  9. 2017-2018 ACM-ICPC Latin American Regional Programming Contest GYM101889

    挺有意思的一套题,题也没有啥毒瘤了,本来是队切的结果种种原因大家全挂机了. 只补了百人题,一共7个,其他的暂时先不补了,,也不会嘛qwq H:签到 #include <bits/stdc++.h ...

  10. linux基础操作1

    date #查看日期cal #查看当月日历cal 2017 #查看某年全年的日历whoami #查看当前登录的用户 #修改网卡,可以上网的步骤vi /etc/sysconfig/network-scr ...