2008-12-18 28 views
18

Tôi có một lớp đơn giản kế thừa từ Bộ sưu tập và thêm một vài thuộc tính. Tôi cần phải tuần tự hóa lớp này thành XML, nhưng XMLSerializer bỏ qua các thuộc tính bổ sung của tôi.XmlSerialize bộ sưu tập tùy chỉnh với Thuộc tính

Tôi cho rằng điều này là do điều trị đặc biệt mà XMLSerializer cung cấp cho các đối tượng ICollection và IEnumerable. Cách tốt nhất xung quanh điều này là gì?

Dưới đây là một số mẫu mã:

using System.Collections.ObjectModel; 
using System.IO; 
using System.Xml.Serialization; 

namespace SerialiseCollection 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var c = new MyCollection(); 
      c.Add("Hello"); 
      c.Add("Goodbye"); 

      var serializer = new XmlSerializer(typeof(MyCollection)); 
      using (var writer = new StreamWriter("test.xml")) 
       serializer.Serialize(writer, c); 
     } 
    } 

    [XmlRoot("MyCollection")] 
    public class MyCollection : Collection<string> 
    { 
     [XmlAttribute()] 
     public string MyAttribute { get; set; } 

     public MyCollection() 
     { 
      this.MyAttribute = "SerializeThis"; 
     } 
    } 
} 

này kết quả đầu ra XML sau (lưu ý MyAttribute là mất tích trong các yếu tố MyCollection):

<?xml version="1.0" encoding="utf-8"?> 
<MyCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <string>Hello</string> 
    <string>Goodbye</string> 
</MyCollection> 

Những gì tôi muốn

<MyCollection MyAttribute="SerializeThis" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <string>Hello</string> 
    <string>Goodbye</string> 
</MyCollection> 

Bất kỳ ý tưởng nào? Đơn giản càng tốt. Cảm ơn.

Trả lời

13

Bộ sưu tập thường không tạo ra những vị trí tốt cho các thuộc tính bổ sung. Cả trong quá trình tuần tự hóa và trong ràng buộc dữ liệu, chúng sẽ bị bỏ qua nếu mục trông giống như một bộ sưu tập (IList, IEnumerable, v.v. - tùy thuộc vào tình huống).

Nếu là tôi, tôi sẽ đóng gói bộ sưu tập - tức là

[Serializable] 
public class MyCollectionWrapper { 
    [XmlAttribute] 
    public string SomeProp {get;set;} // custom props etc 
    [XmlAttribute] 
    public int SomeOtherProp {get;set;} // custom props etc 
    public Collection<string> Items {get;set;} // the items 
} 

Các tùy chọn khác là thực hiện IXmlSerializable (khá nhiều công việc), nhưng điều đó vẫn sẽ không làm việc cho liên kết dữ liệu vv Về cơ bản, đây không phải là cách sử dụng dự kiến.

0

Tôi đã chiến đấu với cùng một vấn đề Romaroo là (muốn thêm thuộc tính vào xml serialization của một lớp thực hiện ICollection). Tôi đã không tìm thấy bất kỳ cách nào để trưng ra các thuộc tính nằm trong lớp sưu tập. Tôi thậm chí đã thử sử dụng thẻ XmlAttribute và làm cho các thuộc tính của tôi hiển thị dưới dạng các thuộc tính của nút gốc, nhưng cũng không có may mắn. Tuy nhiên tôi đã có thể sử dụng thẻ XmlRoot trên lớp của tôi để đổi tên nó từ "ArrayOf ...". Dưới đây là một số tài liệu tham khảo trong trường hợp bạn đang quan tâm:

+0

Xem giải pháp của tôi, bạn có thể thấy nó thú vị. – toddmo

12

Nếu bạn đóng gói, như Marc Gravell cho thấy, đầu của bài viết này giải thích cách làm cho XML của bạn trông giống hệt như bạn mô tả.

http://blogs.msdn.com/youssefm/archive/2009/06/12/customizing-the-xml-for-collections-with-xmlserializer-and-datacontractserializer.aspx

Đó là, thay vì điều này:

<MyCollection MyAttribute="SerializeThis" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Items> 
    <string>Hello</string> 
    <string>Goodbye</string> 
    <Items> 
</MyCollection> 

Bạn có thể có điều này:

<MyCollection MyAttribute="SerializeThis" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
    <string>Hello</string> 
    <string>Goodbye</string> 
</MyCollection> 
+0

@ neilwhitaker1: Tôi đã bình chọn câu trả lời này, nhưng sẽ tốt hơn nếu bạn mô tả kỹ thuật trong câu trả lời thay vì khiến chúng tôi đọc bài đăng trên blog. Bạn vẫn có thể tham khảo bài đăng. –

+1

Bài đăng trên blog trả lời câu hỏi rất tốt với mức chi tiết phù hợp và câu trả lời rất dễ tìm trong bài đăng trên blog. Tôi nghĩ rằng liên kết đến blog trong trường hợp này là thích hợp hơn. – AndrewS

0

Như Neil Whitaker gợi ý và trong trường hợp liên kết của mình chết ..

Tạo một bộ sưu tập bên trong để lưu trữ các chuỗi và áp dụng các thuộc tính XmlElement để che dấu tên bộ sưu tập. Tạo ra cùng một đầu ra xml như thể MyCollection được thừa kế từ Bộ sưu tập, nhưng cũng tuần tự hóa các thuộc tính trên phần tử cha.

[XmlRoot("MyCollection")] 
public class MyCollection 
{ 
    [XmlAttribute()] 
    public string MyAttribute { get; set; } 

    [XmlElement("string")] 
    public Collection<string> unserializedCollectionName { get; set; } 

    public MyCollection() 
    { 
     this.MyAttribute = "SerializeThis"; 
     this.unserializedCollectionName = new Collection<string>(); 
     this.unserializedCollectionName.Add("Hello"); 
     this.unserializedCollectionName.Add("Goodbye"); 
    } 
} 
Các vấn đề liên quan