先來看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);
}