C# xml数组的序列和反序列化
2019-03-15 18:37 若藜520 阅读(3749) 评论(0) 编辑 收藏 举报先来看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 = 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); }