XML 反序列化处理具有默认值的空标签
XML Deserialization handle empty tags with Default values
我想在反序列化期间处理日期时间。如果 xml 没有节点或空值,那么我需要根据我的设置将该值设置为日期时间最小值或最大值的默认值。所以这里的问题是,如果 xml 有 startdate
和像 <startdate></startdate>
这样的空值,那么我得到 null 而不是 DateTime.MinValue。同样,我可能还有一些其他节点,例如 enddate
,它需要 DateTime.MaxValue 作为默认值。如果我不传递标签 startdate
,那么我将得到预期的最小值。那么我如何处理空标签。如果标签为空,我也需要获取 Date Minvalue。
public static void Main()
{
Program t = new Program();
t.DeserializeObject("<OrderedItem><startdate>20210125</startdate><enddate>20210324</enddate></OrderedItem>");
t.DeserializeObject("<OrderedItem></OrderedItem>");
t.DeserializeObject("<OrderedItem><startdate></startdate><enddate></enddate></OrderedItem>"); //In this case i am getting issue, Output will not have default Min and Max Values
}
private void DeserializeObject(string testData)
{
// Create an instance of the XmlSerializer.
XmlSerializer serializer =
new XmlSerializer(typeof(OrderedItem));
// Declare an object variable of the type to be deserialized.
OrderedItem i;
using (TextReader reader = new StringReader(testData))
{
i = (OrderedItem)serializer.Deserialize(reader);
}
Console.Write("Start date is "+i.Startdate.Date+"\n");
Console.Write("End date is "+i.Enddate.Date+"\n\n");
}
public class OrderedItem
{
[XmlElement(ElementName = "startdate")]
[DefaultValue(typeof(DateTime), "0001-01-01T00:00:00")]
public CustomDateTime Startdate {
get;
set;
} = new CustomDateTime { Date = DateTime.MinValue };
[XmlElement(ElementName = "enddate")]
[DefaultValue(typeof(DateTime), "9999-12-31T00:00:00")]
public CustomDateTime Enddate {
get;
set;
} = new CustomDateTime { Date = DateTime.MaxValue };
}
在我的 CustomDateTime 中,我使用的是 IXmlSerializable,下面是部分代码
public class CustomDateTime : IXmlSerializable, IComparable, IComparable<DateTime>
{
static string[] formats = new string[] { "yyyyMMdd", "yyyy-MM-dd" };
[XmlIgnore]
public DateTime? Date
{
get;
set;
}
// here i have CompareTo and other methods which implements interface
public void ReadXml(XmlReader reader)
{
string input = reader.ReadString();
DateTime inputDate;
if (DateTime.TryParseExact(input, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out inputDate))
{
Date = inputDate;
}
else
{
Date = null;
}
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
if (Date != null)
{
writer.WriteString(Date.Value.ToString("yyyyMMdd"));
}
}
}
实际输出
开始日期是 2021 年 1 月 25 日 12:00:00 上午
结束日期是 2021 年 3 月 24 日 12:00:00 上午
开始日期是 1/1/0001 12:00:00 上午
结束日期是 12/31/9999 11:59:59 下午
开始日期是
结束日期是
预期输出
开始日期是 2021 年 1 月 25 日 12:00:00 上午
结束日期是 2021 年 3 月 24 日 12:00:00 上午
开始日期是 1/1/0001 12:00:00 上午
结束日期是 12/31/9999 11:59:59 下午
开始日期是 1/1/0001 12:00:00 上午
结束日期是 12/31/9999 11:59:59 下午
Fiddle:https://dotnetfiddle.net/qv7sjP
我想我可以根据需要添加 [DefaultValue(typeof(DateTime), "0001-01-01T00:00:00")]
或 [DefaultValue(typeof(DateTime), "9999-12-31T00:00:00")]
等默认值属性到 属性 Startdate
和 Enddate
并在 [=21] 中阅读=] 方法,然后在标记不存在(else 块)时在 ReadXml 方法中设置日期 属性。我不确定如何阅读和处理它。我也不确定这个解决方案是否合适
尝试以下操作:
public class OrderedItem
{
private DateTime _Startdate = new DateTime();
[XmlElement(ElementName = "startdate")]
public DateTime Startdate {
get{ return _Startdate;}
set{ _Startdate = value;}
}
private DateTime _Enddate = new DateTime();
[XmlElement(ElementName = "enddate")]
public DateTime Enddate
{
get { return _Enddate; }
set { _Enddate = value; }
}
}
我想在反序列化期间处理日期时间。如果 xml 没有节点或空值,那么我需要根据我的设置将该值设置为日期时间最小值或最大值的默认值。所以这里的问题是,如果 xml 有 startdate
和像 <startdate></startdate>
这样的空值,那么我得到 null 而不是 DateTime.MinValue。同样,我可能还有一些其他节点,例如 enddate
,它需要 DateTime.MaxValue 作为默认值。如果我不传递标签 startdate
,那么我将得到预期的最小值。那么我如何处理空标签。如果标签为空,我也需要获取 Date Minvalue。
public static void Main()
{
Program t = new Program();
t.DeserializeObject("<OrderedItem><startdate>20210125</startdate><enddate>20210324</enddate></OrderedItem>");
t.DeserializeObject("<OrderedItem></OrderedItem>");
t.DeserializeObject("<OrderedItem><startdate></startdate><enddate></enddate></OrderedItem>"); //In this case i am getting issue, Output will not have default Min and Max Values
}
private void DeserializeObject(string testData)
{
// Create an instance of the XmlSerializer.
XmlSerializer serializer =
new XmlSerializer(typeof(OrderedItem));
// Declare an object variable of the type to be deserialized.
OrderedItem i;
using (TextReader reader = new StringReader(testData))
{
i = (OrderedItem)serializer.Deserialize(reader);
}
Console.Write("Start date is "+i.Startdate.Date+"\n");
Console.Write("End date is "+i.Enddate.Date+"\n\n");
}
public class OrderedItem
{
[XmlElement(ElementName = "startdate")]
[DefaultValue(typeof(DateTime), "0001-01-01T00:00:00")]
public CustomDateTime Startdate {
get;
set;
} = new CustomDateTime { Date = DateTime.MinValue };
[XmlElement(ElementName = "enddate")]
[DefaultValue(typeof(DateTime), "9999-12-31T00:00:00")]
public CustomDateTime Enddate {
get;
set;
} = new CustomDateTime { Date = DateTime.MaxValue };
}
在我的 CustomDateTime 中,我使用的是 IXmlSerializable,下面是部分代码
public class CustomDateTime : IXmlSerializable, IComparable, IComparable<DateTime>
{
static string[] formats = new string[] { "yyyyMMdd", "yyyy-MM-dd" };
[XmlIgnore]
public DateTime? Date
{
get;
set;
}
// here i have CompareTo and other methods which implements interface
public void ReadXml(XmlReader reader)
{
string input = reader.ReadString();
DateTime inputDate;
if (DateTime.TryParseExact(input, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out inputDate))
{
Date = inputDate;
}
else
{
Date = null;
}
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
if (Date != null)
{
writer.WriteString(Date.Value.ToString("yyyyMMdd"));
}
}
}
实际输出
开始日期是 2021 年 1 月 25 日 12:00:00 上午 结束日期是 2021 年 3 月 24 日 12:00:00 上午
开始日期是 1/1/0001 12:00:00 上午 结束日期是 12/31/9999 11:59:59 下午
开始日期是 结束日期是
预期输出
开始日期是 2021 年 1 月 25 日 12:00:00 上午 结束日期是 2021 年 3 月 24 日 12:00:00 上午
开始日期是 1/1/0001 12:00:00 上午 结束日期是 12/31/9999 11:59:59 下午
开始日期是 1/1/0001 12:00:00 上午 结束日期是 12/31/9999 11:59:59 下午
Fiddle:https://dotnetfiddle.net/qv7sjP
我想我可以根据需要添加 [DefaultValue(typeof(DateTime), "0001-01-01T00:00:00")]
或 [DefaultValue(typeof(DateTime), "9999-12-31T00:00:00")]
等默认值属性到 属性 Startdate
和 Enddate
并在 [=21] 中阅读=] 方法,然后在标记不存在(else 块)时在 ReadXml 方法中设置日期 属性。我不确定如何阅读和处理它。我也不确定这个解决方案是否合适
尝试以下操作:
public class OrderedItem
{
private DateTime _Startdate = new DateTime();
[XmlElement(ElementName = "startdate")]
public DateTime Startdate {
get{ return _Startdate;}
set{ _Startdate = value;}
}
private DateTime _Enddate = new DateTime();
[XmlElement(ElementName = "enddate")]
public DateTime Enddate
{
get { return _Enddate; }
set { _Enddate = value; }
}
}