2011-01-17 12 views
5

は、私はそれがカスタムデータ型を持つ要素を持って管理していないXML文書を持って逆シリアル化のカスタムXMLデータ型は

<foo> 
    <time type="epoch_seconds">1295027809.26896</time> 
</foo> 

私は自動的にエポック秒に変換することができ、クラスを持っているしたいと思います:

[Serializable] 
public class Foo 
{ 
     public Foo() 
     { 
     } 

     public EpochTime Time { get; set; } 
} 

XMLシリアライザはtype="epoch_time"でXMLを見つけたときにそれを使用する知っているようにEpochTimeクラスを定義する方法はありますか?もしそうなら、WriteXmlReadXmlを設定するにはどうしたらいいですか?

+0

( '[Serializable]'はxmlシリアル化に影響する) –

答えて

4

通常の方法は、あなたが期待するように動作プロパティでそれを単にシムことです:

public class EpochTime { 
    public enum TimeType { 
     [XmlEnum("epoch_seconds")] Seconds 
    } 
    [XmlAttribute("type")] public TimeType Type {get;set;} 
    [XmlText] public string Text {get;set;} 

    [XmlIgnore] public DateTime Value { 
     get { /* your parse here */ } 
     set { /* your format here */ } 
    } 
} 

も、あなたが必要になります。

[XmlElement("time")] 
public EpochTime Time { get; set; } 

をここにあなたとの完全な例ですxml:

using System; 
using System.IO; 
using System.Xml; 
using System.Xml.Serialization; 
static class Program 
{ 
    static void Main() 
    { 
     Foo foo; 
     var ser = new XmlSerializer(typeof(Foo)); 
     using (var reader = XmlReader.Create(new StringReader(@"<foo> 
    <time type=""epoch_seconds"">1295027809.26896</time> 
</foo>"))) 
     { 
      foo = (Foo)ser.Deserialize(reader); 
     } 
    } 
} 
public class EpochTime 
{ 
    public enum TimeType 
    { 
     [XmlEnum("epoch_seconds")] 
     Seconds 
    } 
    [XmlAttribute("type")] 
    public TimeType Type { get; set; } 
    [XmlText] 
    public string Text { get; set; } 
    private static readonly DateTime Epoch = new DateTime(1970, 1, 1); 
    [XmlIgnore] public DateTime Value 
    { 
     get 
     { 
      switch (Type) 
      { 
       case TimeType.Seconds: 
        return Epoch + TimeSpan.FromSeconds(double.Parse(Text)); 
       default: 
        throw new NotSupportedException(); 
      } 
     } 
     set { 
      switch (Type) 
      { 
       case TimeType.Seconds: 
        Text = (value - Epoch).TotalSeconds.ToString(); 
        break; 
       default: 
        throw new NotSupportedException(); 
      } 
     } 
    } 
} 
[XmlRoot("foo")] 
public class Foo 
{ 
    public Foo() 
    { 
    } 

    [XmlElement("time")] 
    public EpochTime Time { get; set; } 
} 
0

実際にISerializableを実装する必要がありますか?次はあなたのシナリオに働くかもしれない:

public class EpochTime 
{ 
    [XmlText] 
    public double Data { get; set; } 
    [XmlAttribute("type")] 
    public string Type { get; set; } 
} 

public class Foo 
{ 
    public EpochTime Time { get; set; } 
} 

class Program 
{ 
    public static void Main() 
    { 
     var foo = new Foo 
     { 
      Time = new EpochTime 
      { 
       Data = 1295027809.26896, 
       Type = "epoch_seconds" 
      } 
     }; 
     var serializer = new XmlSerializer(foo.GetType()); 
     serializer.Serialize(Console.Out, foo); 
    } 
} 

[Serializable]XmlSerializerに影響を与えないことに気づきます。

関連する問題