【问题标题】:XML Deserialization handle empty tags with Default valuesXML反序列化处理具有默认值的空标签
【发布时间】:2021-05-26 16:35:14
【问题描述】:

我想在反序列化期间处理日期时间。如果 xml 没有节点或空值,那么我需要根据我设置的值将值设置为日期时间最小值或最大值的默认值。所以这里的问题是如果xml有startdate<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

开始日期是 结束日期是

预期输出

开始日期是 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

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

小提琴: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# .net xml deserialization


    【解决方案1】:

    尝试以下:

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

    【讨论】:

    • 我使用的是 CustomDate 类而不是 Datetime。但是根据您的建议,我使用 CustomDate 修改了我的代码,它不会解决原始问题。请参阅小提琴以获取参考 dotnetfiddle.net/K5Z9gR 。我根据您提供的建议创建了这个,如果我做错了什么请告诉我
    • 我会在 CustomDateTime 中创建默认构造函数 new DateTime : public CustomDateTime() { Date = new DateTime();}
    • 好的。但我不希望当前日期时间成为默认值。我想要基于我的属性的 DateTime 最小值或最大值。我也指定了它们。在有问题的共享代码中,我采用了 3 个示例 XML 输入。我在第三种情况下面临问题
    • new DataTime() 是 1/1/01。 public CustomDateTime(DateTime date) { Date = date;}
    • 好的。如果我这样做。开始日期和结束日期都将具有相同的默认日期 01 年 1 月 1 日。但我想设置不同的默认值(在问题中提到,我正在尝试最小值和最大值)。当 XML 具有空值节点时,也会发生我的问题。所以这是在构造函数中设置值之后发生的。因此,在我的情况下,该值将被空覆盖。从有问题的小提琴共享中,我能够重现该问题。我觉得您没有理解我在问题中提到的原始问题。如果我遗漏了什么或者我需要适当地重写问题,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多