问题
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:
- My top request is changing
MyRoot.Time
type fromlong
toDateTime
. It can be achieve easily by code using DateTime.FromFileTimeUtc or new DateTime, but can it be done directly by the XmlSerializer? - Can I change
MyRoot.Children
type into something more complex likeDictionary<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,
}
回答1:
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;
}
}
}
回答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.
来源:https://stackoverflow.com/questions/5089310/how-to-deserialize-xml-attribute-of-type-long-to-utc-datetime