2008-12-18 30 views
18

我有一個簡單的類繼承自Collection並添加了一些屬性。我需要將此類序列化爲XML,但XMLSerializer忽略了我的其他屬性。XmlSerialize具有屬性的自定義集合

我認爲這是由於XMLSerializer給出了ICollection和IEnumerable對象的特殊待遇。最好的解決辦法是什麼?

下面是一些示例代碼:

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"; 
     } 
    } 
} 

此輸出下面的XML(注意MyAttribute缺少在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> 

<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> 

任何想法?越簡單越好。謝謝。

回答

13

集合通常不會成爲額外屬性的好地方。在序列化和數據綁定期間,如果項目看起來像集合(IListIEnumerable等 - 取決於方案),它們將被忽略。

如果是我,我會封裝集合 - 即

[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 
} 

另一種選擇是實現IXmlSerializable(相當多的工作),但仍然不會爲數據綁定等工作基本上,這不是預期的用法。

0

我一直在與同一個問題爭鬥Romaroo(想要添加屬性到實現ICollection的類的xml序列化)。我還沒有找到任何方法來顯示集合類中的屬性。我甚至嘗試過使用XmlAttribute標記,並將我的屬性顯示爲根節點的屬性,但是也沒有運氣。然而,我卻能夠在我的課堂上使用XmlRoot標籤來將其重命名爲「ArrayOf ...」。這裏有一些參考的情況下,你有興趣:

+0

看到我的解決方案,您可能會覺得它很有趣。 – toddmo 2015-01-24 23:06:28

12

如果封裝,如馬克·Gravell指出,這篇文章的開頭介紹瞭如何讓你的XML看起來完全像你描述的。

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

也就是說,是不是這樣的:

<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> 

你可以有這樣的:

<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:我提出了這個答案,但如果你在答案中描述了技術,而不是讓我們去閱讀博客文章,它會更好。您仍然可以參考該帖子。 – 2010-03-25 19:19:56

0

尼爾·惠特克建議和情況下,他死鏈接..

創建一個內集合來存儲字符串和應用的XmlElement屬性掩蓋集合名稱。與MyCollection繼承自Collection一樣,生成相同的xml輸出,但也會序列化父元素上的屬性。

[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"); 
    } 
}