2012-01-09 27 views
14

Tôi đang cố gắng tạo C# tạo ra một đoạn XML như thế này.Làm thế nào để cung cấp cho một mảng một thuộc tính trong quá trình tuần tự hóa trong C#?

<device_list type="list"> 
    <item type="MAC">11:22:33:44:55:66:77:88</item> 
    <item type="MAC">11:22:33:44:55:66:77:89</item> 
    <item type="MAC">11:22:33:44:55:66:77:8A</item> 
</device_list> 

Tôi đã nghĩ đến việc sử dụng một cái gì đó như thế này:

[XmlArray("device_list"), XmlArrayItem("item")] 
public ListItem[] device_list { get; set; } 

như bất động sản, với khai báo lớp này:

public class ListItem { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlText] 
    public string Value { get; set; } 
} 

nào mang lại cho tôi serialization bên trong, nhưng tôi don' t biết cách áp dụng thuộc tính type="list" cho số device_list ở trên.

Tôi đang nghĩ (nhưng không chắc chắn làm thế nào để viết cú pháp) mà tôi cần phải làm một:

public class DeviceList { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlArray] 
    public ListItem[] .... This is where I get lost 
} 

cập nhật dựa trên phản ứng của Dave

public class DeviceList : List<ListItem> { 
    [XmlAttribute] 
    public string type { get; set; } 
} 

public class ListItem { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlText] 
    public string Value { get; set; } 
} 

và việc sử dụng hiện nay là :

[XmlArray("device_list"), XmlArrayItem("item")] 
public DeviceList device_list { get; set; } 

Và loại, khi được khai báo trong mã như sau:

device_list = new DeviceList{type = "list"} 
device_list.Add(new ListItem { type = "MAC", Value = "1234566" }); 
device_list.Add(new ListItem { type = "MAC", Value = "1234566" }); 

Không hiển thị loại trên tuần tự hóa. Đây là kết quả của serialization:

<device_list> 
    <item type="MAC">1234566</item> 
    <item type="MAC">1234566</item> 
</device_list> 

Vì vậy, rõ ràng là tôi vẫn đang thiếu một cái gì đó ...

+0

@ jcolebrand- Bạn cần phải thêm một thuộc tính XmlElement đến tài sản ListType của lớp DeviceList. Xem cập nhật của tôi dưới đây. –

+0

@ jcolebrand- Đây là một số tài liệu tham khảo tốt về XML serializaton: http://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.80).aspx –

Trả lời

11

Sử dụng một phần của câu trả lời của Dave ở trên, tôi thấy rằng nó là tốt nhất để sử dụng tài sản trong khai báo lớp như thế này: (lưu ý việc thiếu các thuộc tính)

public DeviceList device_list { get; set; } 

và sau đó cập nhật các lớp DeviceList như thế này:

01.
[XmlType("device_list")] 
[Serializable] 
public class DeviceList { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlElement("item")] 
    public ListItem[] items { get; set; } 
} 

và giữ cho lớp ListItem gốc

public class ListItem { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlText] 
    public string Value { get; set; } 
} 

và serialization của tôi là như mong đợi:

<device_list type="list"> 
    <item type="MAC">1234567</item> 
    <item type="MAC">123456890</item> 
</device_list> 
+0

thật đơn giản. +1 – yas4891

+0

Tôi mất một thời gian để hiểu rằng việc thêm thuộc tính [XmlElement] là chìa khóa ở đây. Theo MSDN: _Nếu bạn áp dụng XmlElementAttribute cho một trường hoặc thuộc tính trả về một mảng, các mục trong mảng được mã hóa như một chuỗi các phần tử XML. Ngược lại nếu XmlElementAttribute không được áp dụng cho trường hoặc thuộc tính như vậy, các mục trong mảng được mã hóa dưới dạng chuỗi các phần tử, lồng trong phần tử được đặt tên theo trường hoặc thuộc tính._ – SlimShaggy

+0

. Dường như bạn thậm chí có thể áp dụng nhiều tham chiếu XmlElement nếu bạn có nhiều hơn một kiểu con với cùng một kiểu gốc. – ravuya

3

Thay vì sử dụng một ListItem[], dẫn xuất một lớp mới từ List<T> gọi DeviceList:

public class DeviceList : List<ListItem> 
{ 
    [XmlElement(ElementName = "type")] 
    public string ListType {get;set;} 

} 

Sau đó, trong một lớp có chứa sử dụng lớp đó để tuần tự hóa XML. Giá trị kiểu có thể được bao gồm như một phần tử của nút cha, tùy thuộc vào cách bạn định cấu hình tuần tự hóa. Tôi không nhớ cú pháp chính xác, nhưng tôi nghĩ rằng các thuộc tính lớp được thêm vào như là các phần tử nút theo mặc định.

Chứa lớp:

public class SerializeMyStuff 
{ 
    public SeriazlieMyStuff() 
    { 
     ListOfDevices = new DeviceList(); 
     ListOfDevices.ListType = "list"; 
    } 

    [XmlArray("device_list"), XmlArrayItem("item")] 
    public DeviceList ListOfDevices {get;set;} 
} 
+0

vì vậy nơi tôi sử dụng '[XmlArray (" device_list "), XmlArrayItem ("mục")] công khai ListItem [] device_list {get; bộ; } 'Bạn đang gợi ý tôi nên làm gì thay thế? Xin lỗi vì dày đặc, tôi chỉ cảm thấy như tôi đang thiếu một cái gì đó ở đây ... – jcolebrand

+0

ListItem [] là một mảng nguyên thủy của ListItems. Nếu bạn tạo một lớp mới có nguồn gốc từ Danh sách , bạn có thể thêm thuộc tính "loại" mới vào lớp đó. Điều đó sẽ cho bạn khả năng thiết lập phần tử "type" trong XML được tuần tự hóa. –

+0

Đã cập nhật Q, vì vậy bạn có thể xem những gì tôi đang làm và nơi tôi không nhìn thấy sự tuần tự hóa. Tôi đang làm gì sai? – jcolebrand

2

Bạn cũng có thể đạt được các hành vi mong muốn bằng cách thực hiện [IXmlSerializable][1] trong lớp container của bạn:

Với mã dưới đây tôi nhận được đánh dấu sau:

<?xml version="1.0"?> 
<DeviceList type="list"> 
    <Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="MAC">11:22:33:44:55:66:77:88</Item> 
    <Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="MAC">11:22:33:44:55:66:77:89</Item> 
    <Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="MAC">11:22:33:44:55:66:77:8A</Item> 
</DeviceList> 

mã:

public class Item 
{ 
    [XmlAttribute("type")] 
    public string Type { get; set; } 

    [XmlText] 
    public string Value { get; set; } 
} 

public class DeviceList : IXmlSerializable 
{ 
    public string Type { get; set; } 

    public List<Item> Items { get; set; } 


    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     reader.MoveToContent(); 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     writer.WriteAttributeString("type", Type); 


     XmlSerializer serializer = new XmlSerializer(typeof(Item)); 
     foreach (var item in Items) 
     { 
      serializer.Serialize(writer, item); 
     } 
    } 
} 

tôi sử dụng đoạn mã sau vào phương pháp chính của tôi:

var dlist = new DeviceList 
       { 
        Type = "list", 
        Items = new List<Item> 
           { 
            new Item {Type = "MAC", Value = "11:22:33:44:55:66:77:88"}, 
            new Item {Type = "MAC", Value = "11:22:33:44:55:66:77:89"}, 
            new Item {Type = "MAC", Value = "11:22:33:44:55:66:77:8A"}, 
           } 
       }; 


using(FileStream stream = new FileStream(@"D:\jcoletest.xml", FileMode.Create, FileAccess.Write)) 
{ 
    new XmlSerializer(typeof (DeviceList)).Serialize(stream, dlist); 
} 

Để biết thêm thông tin xem xét điều này tutorial here

Các vấn đề liên quan