C# 中xml數組的序列和反序列化方法

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

複製代碼

複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章