热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> .Net编程>>正文内容

在.net 当中如何XML序列化一个Collection

发布时间:2010年03月07日点击数: 佚名

Collection主要是指像Array, ArrayList, List, Dictionary, HashTable这些数据类型,大家平时用的很多。如果一个类中有一个Collection类型的成员,在对这个类进行XML序列化的时候,应该如何处理?应该说在.net当中这是比较简单的,只要建立一个XmlSerializer类就可以帮你自动搞定,不过有的时候你可能需要对自动的序列化过程施加更多的控制,比如XML的结构是实现固定的,你必须按照要求去生成XML结构。
使用不同的属性可以灵活的控制生成的XML,这里我就不多介绍了,主要讲一下如何序列化比较复杂的Collection结构。下面的方法,对于所有实现了IEnumerable接口的Collection都有效。
我使用MSDN中的例子,不过没有使用数组或者ArrayList,而是使用了比较高级的数据类型List<T>,希望在讲解如何序列化XML的同时给使用List<T>的同学提供点参考。
序列化一个List<T>

下面的代码示范了如何序列化一个List<T>,实际上和序列化其它类一样,把这个类扔给Serialize()函数即可。

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Text; 
  5. using System.Xml.Serialization; 
  6. using System.IO; 
  7.   
  8. namespace SerializeCollection 
  9.     class Program 
  10.     { 
  11.         static void Main(string[] args) 
  12.         { 
  13.             Program test = new Program(); 
  14.             test.SerializeDocument("e:\\books.xml"); 
  15.         } 
  16.   
  17.         public void SerializeDocument(string filename) 
  18.         { 
  19.             // Creates a new XmlSerializer. 
  20.             XmlSerializer s = 
  21.             new XmlSerializer(typeof(MyRootClass)); 
  22.   
  23.             // Writing the file requires a StreamWriter. 
  24.             TextWriter myWriter = new StreamWriter(filename); 
  25.   
  26.             // Creates an instance of the class to serialize.  
  27.             MyRootClass myRootClass = new MyRootClass(); 
  28.              
  29.             //create items 
  30.             Item item1 = new Item(); 
  31.             // Sets the objects' properties. 
  32.             item1.ItemName = "Widget1"
  33.             item1.ItemCode = "w1"
  34.             item1.ItemPrice = 231; 
  35.             item1.ItemQuantity = 3; 
  36.   
  37.              
  38.             Item item2 = new Item(); 
  39.             // Sets the objects' properties. 
  40.             item2.ItemName = "Widget2"
  41.             item2.ItemCode = "w2"
  42.             item2.ItemPrice = 800; 
  43.             item2.ItemQuantity = 2; 
  44.   
  45.             // Sets the class's Items property to the list. 
  46.             myRootClass.Items.Add(item1); 
  47.             myRootClass.Items.Add(item2); 
  48.   
  49.             /* Serializes the class, writes it to disk, and closes  
  50.                the TextWriter. */ 
  51.             s.Serialize(myWriter, myRootClass); 
  52.             myWriter.Close(); 
  53.         } 
  54.   
  55.     } 
  56.   
  57.     // This is the class that will be serialized. 
  58.     [Serializable] 
  59.     public class MyRootClass 
  60.     { 
  61.         public MyRootClass() 
  62.         { 
  63.             items = new List<Item>(); 
  64.         } 
  65.   
  66.         private List<Item> items; 
  67.   
  68.         public List<Item> Items 
  69.         { 
  70.             get { return items; } 
  71.             set { items = value; } 
  72.         } 
  73.     } 
  74.   
  75.     public class Item 
  76.     { 
  77.         [XmlElement(ElementName = "OrderItem")] 
  78.         public string ItemName; 
  79.         public string ItemCode; 
  80.         public decimal ItemPrice; 
  81.         public int ItemQuantity; 
  82.     } 
  83.   
  84.   

最后序列化成的XML:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <MyRootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  3.   <Items> 
  4.     <Item> 
  5.       <OrderItem>Widget1</OrderItem> 
  6.       <ItemCode>w1</ItemCode> 
  7.       <ItemPrice>231</ItemPrice> 
  8.       <ItemQuantity>3</ItemQuantity> 
  9.     </Item> 
  10.     <Item> 
  11.       <OrderItem>Widget2</OrderItem> 
  12.       <ItemCode>w2</ItemCode> 
  13.       <ItemPrice>800</ItemPrice> 
  14.       <ItemQuantity>2</ItemQuantity> 
  15.     </Item> 
  16.   </Items> 
  17. </MyRootClass> 

如果这个List<T>中的成员的类还有继承关系

现在把情况变得复杂一点,因为多态,List<T>中的类可能是指定类型的子类型,这个时候会出现什么情况呢?
我们增加一个BookItem类,继承自Item 类。

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Text; 
  5. using System.Xml.Serialization; 
  6. using System.IO; 
  7.   
  8. namespace SerializeCollection 
  9.     class Program 
  10.     { 
  11.         static void Main(string[] args) 
  12.         { 
  13.             Program test = new Program(); 
  14.             test.SerializeDocument("e:\\books.xml"); 
  15.         } 
  16.   
  17.         public void SerializeDocument(string filename) 
  18.         { 
  19.             // Creates a new XmlSerializer. 
  20.             XmlSerializer s = 
  21.             new XmlSerializer(typeof(MyRootClass)); 
  22.   
  23.             // Writing the file requires a StreamWriter. 
  24.             TextWriter myWriter = new StreamWriter(filename); 
  25.   
  26.             // Creates an instance of the class to serialize.  
  27.             MyRootClass myRootClass = new MyRootClass(); 
  28.   
  29.             /* Uses a more advanced method of creating an list: 
  30.          create instances of the Item and BookItem, where BookItem  
  31.          is derived from Item. */ 
  32.             Item item1 = new Item(); 
  33.             // Sets the objects' properties. 
  34.             item1.ItemName = "Widget1"
  35.             item1.ItemCode = "w1"
  36.             item1.ItemPrice = 231; 
  37.             item1.ItemQuantity = 3; 
  38.   
  39.             BookItem bookItem = new BookItem(); 
  40.             // Sets the objects' properties. 
  41.             bookItem.ItemCode = "w2"
  42.             bookItem.ItemPrice = 123; 
  43.             bookItem.ItemQuantity = 7; 
  44.             bookItem.ISBN = "34982333"
  45.             bookItem.Title = "Book of Widgets"
  46.             bookItem.Author = "John Smith"
  47.   
  48.             // Sets the class's Items property to the list. 
  49.             myRootClass.Items.Add(item1); 
  50.             myRootClass.Items.Add(bookItem); 
  51.   
  52.             /* Serializes the class, writes it to disk, and closes  
  53.                the TextWriter. */ 
  54.             s.Serialize(myWriter, myRootClass); 
  55.             myWriter.Close(); 
  56.         } 
  57.   
  58.     } 
  59.   
  60.     // This is the class that will be serialized. 
  61.     [Serializable] 
  62.     public class MyRootClass 
  63.     { 
  64.         public MyRootClass() 
  65.         { 
  66.             items = new List<Item>(); 
  67.         } 
  68.   
  69.         private List<Item> items; 
  70.   
  71.         public List<Item> Items 
  72.         { 
  73.             get { return items; } 
  74.             set { items = value; } 
  75.         } 
  76.     } 
  77.   
  78.     public class Item 
  79.     { 
  80.         [XmlElement(ElementName = "OrderItem")] 
  81.         public string ItemName; 
  82.         public string ItemCode; 
  83.         public decimal ItemPrice; 
  84.         public int ItemQuantity; 
  85.     } 
  86.   
  87.     public class BookItem : Item 
  88.     { 
  89.         public string Title; 
  90.         public string Author; 
  91.         public string ISBN; 
  92.     } 
  93.   
  94.   
  95.   

修改代码后,我们再运行,出现如下错误“不应是类型 SerializeCollection.BookItem。使用 XmlInclude 或 SoapInclude 属性静态指定非已知的类型”,看来是系统在做序列化的时候,搞不清楚List中的成员到底是什么类型。这个时候就要使用XmlArrayItem来帮忙了。MyRootClass类的Item成员前加入XmlArrayItem标志。

  1. [XmlArrayItem(ElementName= "Item",  
  2.    IsNullable=true
  3.    Type = typeof(Item), 
  4.    Namespace = "http://www.aboutdnn.com"), 
  5.    XmlArrayItem(ElementName = "BookItem",  
  6.    IsNullable = true,  
  7.    Type = typeof(BookItem), 
  8.    Namespace = http://www.aboutdnn.com)] 

修改后的代码如下:

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Text; 
  5. using System.Xml.Serialization; 
  6. using System.IO; 
  7.   
  8. namespace SerializeCollection 
  9.     class Program 
  10.     { 
  11.         static void Main(string[] args) 
  12.         { 
  13.             Program test = new Program(); 
  14.             test.SerializeDocument("e:\\books.xml"); 
  15.         } 
  16.   
  17.         public void SerializeDocument(string filename) 
  18.         { 
  19.             // Creates a new XmlSerializer. 
  20.             XmlSerializer s = 
  21.             new XmlSerializer(typeof(MyRootClass)); 
  22.   
  23.             // Writing the file requires a StreamWriter. 
  24.             TextWriter myWriter = new StreamWriter(filename); 
  25.   
  26.             // Creates an instance of the class to serialize.  
  27.             MyRootClass myRootClass = new MyRootClass(); 
  28.   
  29.             /* Uses a more advanced method of creating an list: 
  30.          create instances of the Item and BookItem, where BookItem  
  31.          is derived from Item. */ 
  32.             Item item1 = new Item(); 
  33.             // Sets the objects' properties. 
  34.             item1.ItemName = "Widget1"
  35.             item1.ItemCode = "w1"
  36.             item1.ItemPrice = 231; 
  37.             item1.ItemQuantity = 3; 
  38.   
  39.             BookItem bookItem = new BookItem(); 
  40.             // Sets the objects' properties. 
  41.             bookItem.ItemCode = "w2"
  42.             bookItem.ItemPrice = 123; 
  43.             bookItem.ItemQuantity = 7; 
  44.             bookItem.ISBN = "34982333"
  45.             bookItem.Title = "Book of Widgets"
  46.             bookItem.Author = "John Smith"
  47.   
  48.             // Sets the class's Items property to the list. 
  49.             myRootClass.Items.Add(item1); 
  50.             myRootClass.Items.Add(bookItem); 
  51.   
  52.             /* Serializes the class, writes it to disk, and closes  
  53.                the TextWriter. */ 
  54.             s.Serialize(myWriter, myRootClass); 
  55.             myWriter.Close(); 
  56.         } 
  57.   
  58.     } 
  59.   
  60.     // This is the class that will be serialized. 
  61.     [Serializable] 
  62.     public class MyRootClass 
  63.     { 
  64.         public MyRootClass() 
  65.         { 
  66.             items = new List<Item>(); 
  67.         } 
  68.   
  69.         private List<Item> items; 
  70.   
  71.         [XmlArrayItem(ElementName = "Item"
  72.    IsNullable = true
  73.    Type = typeof(Item), 
  74.    Namespace = "http://www.aboutdnn.com"), 
  75.    XmlArrayItem(ElementName = "BookItem"
  76.    IsNullable = true
  77.    Type = typeof(BookItem), 
  78.    Namespace = "http://www.aboutdnn.com")] 
  79.   
  80.         public List<Item> Items 
  81.         { 
  82.             get { return items; } 
  83.             set { items = value; } 
  84.         } 
  85.     } 
  86.   
  87.     public class Item 
  88.     { 
  89.         [XmlElement(ElementName = "OrderItem")] 
  90.         public string ItemName; 
  91.         public string ItemCode; 
  92.         public decimal ItemPrice; 
  93.         public int ItemQuantity; 
  94.     } 
  95.   
  96.     public class BookItem : Item 
  97.     { 
  98.         public string Title; 
  99.         public string Author; 
  100.         public string ISBN; 
  101.     } 
  102.   
  103.   
  104.   

序列化后的XML如下:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <MyRootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  3.   <Items> 
  4.     <Item xmlns="http://www.aboutdnn.com"> 
  5.       <OrderItem>Widget1</OrderItem> 
  6.       <ItemCode>w1</ItemCode> 
  7.       <ItemPrice>231</ItemPrice> 
  8.       <ItemQuantity>3</ItemQuantity> 
  9.     </Item> 
  10.     <BookItem xmlns="http://www.aboutdnn.com"> 
  11.       <ItemCode>w2</ItemCode> 
  12.       <ItemPrice>123</ItemPrice> 
  13.       <ItemQuantity>7</ItemQuantity> 
  14.       <Title>Book of Widgets</Title> 
  15.       <Author>John Smith</Author> 
  16.       <ISBN>34982333</ISBN> 
  17.     </BookItem> 
  18.   </Items> 
  19. </MyRootClass> 

可以看到,已经根据不同的数据类型,序列化为不同名字的节点。这个时候,如果你还想修改XML中<Items>节点的名字或者添加属性,XmlArrayAttribute可以帮你的忙,这个你可以自己试试。

参考文档:

XmlArrayAttribute Class:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayattribute.aspx

更多模板/案例展示

亚太盛典国际婚纱摄影 本案例由亚太盛典国际婚纱公司所部署,精美的界面,合理的布局是网站的一大特色!
亚太盛典国际婚纱摄影 本案例由亚太盛典国际婚纱公司所部署,精美的界面,合理的布局是网站的一大特色!
关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作