如何将long类型的XML属性反序列化为UTC DateTime?

时间:2011-02-23 09:56:59

标签: c# .net utc xmlserializer

关注these answers,我决定使用xsd.exeXmlSerializer作为解析XML的最简单方法。

但我想要一些改进:

  1. 我的最高要求是将MyRoot.Time类型从long更改为DateTime。可以使用DateTime.FromFileTimeUtcnew DateTime通过代码轻松实现,但可以通过XmlSerializer直接完成吗?
  2. 我可以将MyRoot.Children类型更改为更复杂的内容,例如Dictionary<string,Tuple<int,ChildState>>吗?
  3. 我的XML:

    <Root timeUTC="129428675154617102">
        <Child key="AAA" value="10" state="OK" />
        <Child key="BBB" value="20" state="ERROR" />
        <Child key="CCC" value="30" state="OK" />
    </Root>
    

    我的班级:

    [XmlRoot]
    [XmlType("Root")]
    public class MyRoot
    {
        [XmlAttribute("timeUTC")]
        public long Time { get; set; }
    
        [XmlElement("Child")]
        public MyChild[] Children{ get; set; }
    }
    
    [XmlType("Child")]
    public class MyChild
    {
        [XmlAttribute("key")]
        public string Key { get; set; }
    
        [XmlAttribute("value")]
        public int Value { get; set; }
    
        [XmlAttribute("state")]
        public ChildState State { get; set; }
    }
    
    public enum ChildState
    {
        OK,
        BAD,
    }
    

2 个答案:

答案 0 :(得分:1)

我挖掘并在two years old answer Marc Gravell♦中找到了此方法:

public class MyChild
{
    //...

    [XmlIgnore]
    public DateTime Time { get; set; }

    [XmlAttribute("timeUTC")]
    [Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public long TimeInt64 
    {
        get { return Date.ToFileTimeUtc(); }
        set { Date = DateTime.FromFileTimeUtc(value); }
    }
}

这是解决问题#1的公平方法。 #2还没有答案。

答案 1 :(得分:1)

答案仍然是相同的:XmlSerializer不提供此类自定义。您可以对其他功能使用相同的技术,但是,它有点长...(XmlSerializer,正如您所说,简单,您应该考虑使用不同的序列化器来处理此类自定义内容。)

[XmlRoot]
[XmlType("Root")]
public class MyRoot
{
    // ...

    [XmlIgnore]
    public Dictionary<string, Tuple<int, ChildState>> Children { get; set; }

    [XmlElement("Child")]
    public MyChild[] ChildrenRaw
    {
        get
        {
            return Children.Select(c => new MyChild { Key = c.Key, Value = c.Value.Item1, State = c.Value.Item2 }).ToArray();
        }

        set
        {
            var result = new Dictionary<string, Tuple<int, ChildState>>(value.Length);
            foreach(var item in value)
            {
                result.Add(item.Key, new Tuple<int, ChildState>(item.Value, item.State));
            }
            Children = result;
        }
    }
}