HuBeZa
HuBeZa

Reputation: 4761

How to deserialize XML attribute of type long to UTC DateTime?

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

Upvotes: 0

Views: 1647

Answers (2)

HuBeZa
HuBeZa

Reputation: 4761

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.

Upvotes: 1

Mormegil
Mormegil

Reputation: 8071

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

Upvotes: 1

Related Questions