首页 > 解决方案 > XML反序列化处理具有默认值的空标签

问题描述

我想在反序列化期间处理日期时间。如果 xml 没有节点或空值,那么我需要根据我设置的值将值设置为日期时间最小值或最大值的默认值。所以这里的问题是如果xmlstartdate有空值,<startdate></startdate>那么我得到null而不是DateTime.MinValue。同样,我可能有一些其他节点,例如enddate需要 DateTime.MaxValue 作为默认值。如果我没有通过标签startdate,那么我会得到预期的 Minvalue。那么我如何处理空标签。如果标签为空,我也需要获取 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"));
        }
    }
}

实际输出

开始日期是 1/25/2021 12:00:00 AM 结束日期是 3/24/2021 12:00:00 AM

开始日期是 1/1/0001 12:00:00 AM 结束日期是 12/31/9999 11:59:59 PM

开始日期是 结束日期是

预期产出

开始日期是 1/25/2021 12:00:00 AM 结束日期是 3/24/2021 12:00:00 AM

开始日期是 1/1/0001 12:00:00 AM 结束日期是 12/31/9999 11:59:59 PM

开始日期是 1/1/0001 12:00:00 AM 结束日期是 12/31/9999 11:59:59 PM

小提琴:https ://dotnetfiddle.net/qv7sjP

我想我可以像[DefaultValue(typeof(DateTime), "0001-01-01T00:00:00")][DefaultValue(typeof(DateTime), "9999-12-31T00:00:00")]根据需要向属性添加默认值属性StartdateEnddate并在方法中读取它ReadXml,然后在标签不存在时在 ReadXml 方法中设置 Date 属性(其他块)。我不确定如何阅读和处理它。我也不确定这是不是合适的解决方案

标签: c#.netxmldeserialization

解决方案


尝试以下:

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

推荐阅读