2012-07-24 41 views
7

我實現IXmlSerializable低於其編碼RGB顏色值作爲一個字符串類型:如何使用自定義IXmlSerializable作爲XmlAttribute?

public class SerializableColor : IXmlSerializable 
{ 
    public int R { get; set; } 
    public int G { get; set; } 
    public int B { get; set; } 

    public XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public void ReadXml(XmlReader reader) 
    { 
     var data = reader.ReadString(); 
     reader.ReadEndElement(); 
     var split = data.Split(' '); 
     R = int.Parse(split[0]); 
     G = int.Parse(split[1]); 
     B = int.Parse(split[2]); 
    } 

    public void WriteXml(XmlWriter writer) 
    { 
     writer.WriteString(R + " " + G + " " + B); 
    } 
} 

因爲它是一個字符串,我想把它保存爲一個屬性,以節省空間。但只要我添加[XmlAttribute]我的財產,我得到以下異常:{「無法序列成員類型SerializableColor的‘顏色’XmlAttribute/XMLTEXT不能用來編碼類型執行IXmlSerializable的」}

有沒有辦法讓它作爲一個屬性工作?

回答

4

錯誤的含義正是它所說的。當實現IXmlSerializable時,您不能使用這些XML序列化屬性,因爲IXmlSerializable期望XML序列化完全自定義。如果要使用屬性使XmlSerializer可序列化,則可以執行此操作。

[XmlRoot("SerializableColor")] 
public class SerializableColor 
{ 
    [XmlAttribute("R")] 
    public int R { get; set; } 
    [XmlAttribute("G")] 
    public int R { get; set; } 
    [XmlAttribute("B")] 
    public int B { get; set; }  
} 

此外,爲您實現XmlSerializable的:

public void ReadXml(XmlReader reader) 
    { 
     string data = null; 

     reader.MoveToAttribute("Color"); 
     if (reader.ReadAttributeValue()) 
     { 
      data = reader.Value; 
     } 
     reader.ReadEndElement(); 

     var split = data.Split(' '); 
     R = int.Parse(split[0]); 
     G = int.Parse(split[1]); 
     B = int.Parse(split[2]); 
    } 

    public void WriteXml(XmlWriter writer) 
    { 
     writer.WriteAttributeString("Color", R + " " + G + " " + B); 
    } 

如果,另一方面,你正在尋找能夠做的是有一個顏色,是可逆的短字符串represenation ,看看ColorTranslator Class。具體來說,請參閱FromHtml和ToHtml方法。

+0

謝謝你的回答。但我有兩個問題。首先,實施過程如何不正確?看起來非常像[在文檔中]給出的示例(http://msdn.microsoft.com/zh-cn/library/system.xml.serialization.ixmlserializable.aspx)(在註釋部分中描述了附錄)。第二,這個例子中的XmlRoot屬性是相關的嗎?它有什麼不同? – 2012-07-24 19:33:49

+0

關於不生成正確XML的實現,我忘記了「框架寫入一個包裝器元素並在啓動後定位XML編寫器」。我會修改答案。實際上,XmlRoot可以由XmlSerializer推斷出來,但是,當我重寫某個類的默認序列化行爲時,爲了清楚起見,我通常在它的所有組件上執行此操作。 – JamieSee 2012-07-24 20:24:13

+0

因爲OP詢問誰來創建可自定義的XML屬性,所以我投了票。不產生一個XML元素。 – 2012-10-03 08:44:37

6

可悲的是(&奇怪),它根據這個鏈接http://connect.microsoft.com/VisualStudio/feedback/details/277641/xmlattribute-xmltext-cannot-be-used-to-encode-types-implementing-ixmlserializable

是不可能變通的問題,我目前使用的XmlIgnore屬性隱藏複雜屬性並將其作爲通過其他屬性的字符串

public class MyDto 
{ 
    [XmlAttribute(AttributeName = "complex-attribute")] 
    public string MyComplexPropertyAsString 
    { 
     get { return MyComplexMember.ToString(); } 
     set { MyComplexMember.LoadFromString(value); } 
    } 
    [XmlIgnore] 
    public MyComplexMember At { get; set; } 
}