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

发布于 2024-10-18 23:04:41 字数 1919 浏览 6 评论 0 原文

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

但我想要一些改进:

  1. 我的首要请求是将MyRoot.Time类型从long更改为DateTime。它可以通过使用 DateTime.FromFileTimeUtc 的代码轻松实现新日期时间 ,但是可以直接用XmlSerializer来完成吗?
  2. 我可以将 MyRoot.Children 类型更改为更复杂的类型,例如 Dictionary> 吗?

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

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

But I want some refinements:

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

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

My classes:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ヤ经典坏疍 2024-10-25 23:04:41

答案仍然是相同的: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;
        }
    }
}

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;
        }
    }
}
暮光沉寂 2024-10-25 23:04:41

我挖掘并在 两年前的答案,作者: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 仍然没有答案。

I dig up and found this method in a two years old answer by 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); }
    }
}

This is a fair method that solve question #1. Still no answer on #2.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文