我正在访问第三方API并检索一些XML。我也能够访问xsd,并使用xsd生成用于反序列化的对象,使用XmlSerializer。
XML包含这样的日期:
<modified>2014-08-19T06:39:13.269-0400</modified>
生成的代码如下所示:
[System.Xml.Serialization.XmlElementAttribute(DataType="time")]
public System.DateTime modified {
get {
return this.modifiedField;
}
set {
this.modifiedField = value;
}
}
不幸的是,这会在尝试反序列化时导致错误。
我可以通过用XmlIgnore属性标记它并将这样的代码添加到部分类来解决这个问题:
[XmlElement("modified")]
public string modifiedAsString
{
get { return this.modified.ToString(); }
set { this.modified = System.DateTime.Parse(value); }
}
但是,忽略部分是对生成的类的更改,我必须对所有日期时间进行数百次更改。
我尝试使用MetadataType的东西从外部将属性应用于它,但不幸的是XmlSerializer并没有选择它。
有没有人建议如何在不更改生成的代码或输入XML(我无法控制)的情况下解析它?
答案 0 :(得分:1)
如果您愿意将System.DateTime
更改为自定义包装类,并使用隐式运算符更改为System.DateTime
,则可以。虽然我怀疑这可能比忽略的帮助属性更加突破。
您可以创建一个自定义类型,它将包装基础DateTime
并执行必要的解析。此外,您可以利用XmlTextAttribute
来控制输出以匹配<modified>2014-08-19T06:39:13.269-0400</modified>
架构:
public struct CustomDateTime
{
private DateTime UnderlyingDateTime;
[XmlText]
public string CustomFormat
{
get { return UnderlyingDateTime.ToString(); }
set { UnderlyingDateTime = System.DateTime.Parse(value); }
}
public static implicit operator DateTime(CustomDateTime custom)
{
return custom.UnderlyingDateTime;
}
public static implicit operator CustomDateTime(DateTime datetime)
{
return new CustomDateTime { UnderlyingDateTime = datetime };
}
}
这是包含Modified
属性的类(你没有提到名称,所以我只称它为Foo
):
public class Foo
{
public CustomDateTime Modified { get; set; }
}
隐式运算符允许您在大多数情况下直接读/写DateTime
值:
Foo f = new Foo();
f.Modified = DateTime.Parse("2014-08-19T06:39:13.269-0400");
它支持您的标准耀斑XmlSerializer
序列化:
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
var textwriter = new StringWriter();
serializer.Serialize(textwriter, f);
string xml = textwriter.ToString();
Console.WriteLine(xml);
生成的XML(我已经剥离了一些通常位于根节点中的包装垃圾):
<Foo>
<Modified>2014-08-19 6:39:13 AM</Modified>
</Foo>
反序列化上面的XML:
Foo deserialized = (Foo)serializer.Deserialize(new StringReader(xml));
DateTime datetime = deserialized.Modified;
Console.WriteLine(datetime);
DateTime
输出的结果:2014-08-19 6:39:13 AM
现在,这与完全的XML内容不匹配,即显示“2014-08-19 6:39:13 AM”而不是“2014-08-19T06:39: 13.269-0400“,但仅仅是因为我正在跟踪逐字您对DateTime.ToString()
财产使用DateTime.Parse
和get/set
。
但是,它会很好地读取XML内容,也就是说,如果您的传入XML是:
<Foo>
<Modified>2014-08-19T06:39:13.269-0400</Modified>
</Foo>
它仍然以相同的方式读取它(基本上它会调用System.DateTime.Parse("2014-08-19T06:39:13.269-0400")
)。
编辑:只是为了澄清一下,你必须做出的重大改变就是改变原来的Foo
类:
public class Foo
{
public DateTime Modified { get; set; }
}
对此:
public class Foo
{
public CustomDateTime Modified { get; set; }
}
如果[System.Xml.Serialization.XmlElementAttribute(DataType="time")]
属性的行为在此用法中被正确模拟,我不肯定,但如果不是,则您很容易灵活地实现无论解析您希望在CustomDateTime.CustomFormat
属性getter和setter。