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

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

问题描述:

遵循这些 answers,我决定使用 xsd.exeXmlSerializer 作为解析 XML 的最简单方法.

Following these answers, I've decided to use xsd.exe and XmlSerializer as the most simple way to parse XML.

但我想要一些改进:

  1. 我的首要请求是将 MyRoot.Time 类型从 long 更改为 DateTime.它可以通过使用 DateTime.FromFileTimeUtc 的代码轻松实现新日期时间,但是可以通过 XmlSerializer 直接完成吗?
  2. 我可以将 MyRoot.Children 类型更改为更复杂的类型,例如 Dictionary>?
  1. My top request is changing MyRoot.Time type from long to DateTime. It can be achieve easily by code using DateTime.FromFileTimeUtc or new DateTime, but can it be done directly by the XmlSerializer?
  2. Can I change MyRoot.Children type into something more complex like Dictionary<string,Tuple<int,ChildState>>?

我的 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,
}

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

The answer is still the same: XmlSerializer does not offer such customization. You can use the same technique for the other feature, however, it is a bit longer… (XmlSerializer is, as you said, simple, you should consider different serializers for such custom stuff.)

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