将XML时间反序列化为日期时间?

时间:2014-01-02 22:14:08

标签: c# xml datetime

我有一个第三方XML文件,我需要将其反序列化为对象,但是当我这样做时,我收到一个错误:string was not recognized as a valid datetime。这是因为XML中的时间只是一个时间,格式为HH:mm:SS,而来自第三方的XSD生成的类产生一个datetime字段,该字段期望日期时间不仅仅是时间。

他们给我xml:

<PO>
...
<PurchaseOrderTime>8:00:00</PurchaseOrderTime>
...
</PO> 

Generated类创建一个System.DateTime对象来保存反序列化的PurchaseOrderTime但由于它期望yyyy/MM/dd HH:mm:SS tt的格式而失败,但因为我无法控制它们向我发送xsd或xml的内容,我该怎么做才能解决这个问题?

有没有办法预先处理这个领域以获得我需要的东西?

我是否必须手动将System.DateTime更改为timespan(这不仅仅是一次性字段,否则我会做到这一点)

这样做的最佳方式是什么?

编辑1: 这是来自XSD的生成类

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1015")]
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.spscommerce.com/RSX")]
    [System.Xml.Serialization.XmlRootAttribute("OrderHeader", Namespace="http://www.spscommerce.com/RSX", IsNullable=false)]
    public partial class OrderHeaderType : System.ComponentModel.INotifyPropertyChanged {

        ...

        private System.DateTime purchaseOrderTimeField;

        private bool purchaseOrderTimeFieldSpecified;

        ...

        [System.Xml.Serialization.XmlElementAttribute(DataType="time", Order=7)]
        public System.DateTime PurchaseOrderTime {
            get {
                return this.purchaseOrderTimeField;
            }
            set {
                if ((purchaseOrderTimeField.Equals(value) != true)) {
                    this.purchaseOrderTimeField = value;
                    this.OnPropertyChanged("PurchaseOrderTime");
                }
            }
        }

        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public bool PurchaseOrderTimeSpecified {
            get {
                return this.purchaseOrderTimeFieldSpecified;
            }
            set {
                if ((purchaseOrderTimeFieldSpecified.Equals(value) != true)) {
                    this.purchaseOrderTimeFieldSpecified = value;
                    this.OnPropertyChanged("PurchaseOrderTimeSpecified");
                }
            }
        }


        #region Serialize/Deserialize
        /// <summary>
        /// Serializes current OrderHeaderType object into an XML document
        /// </summary>
        /// <returns>string XML value</returns>
        public virtual string Serialize() {
            System.IO.StreamReader streamReader = null;
            System.IO.MemoryStream memoryStream = null;
            try {
                memoryStream = new System.IO.MemoryStream();
                Serializer.Serialize(memoryStream, this);
                memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
                streamReader = new System.IO.StreamReader(memoryStream);
                return streamReader.ReadToEnd();
            }
            finally {
                if ((streamReader != null)) {
                    streamReader.Dispose();
                }
                if ((memoryStream != null)) {
                    memoryStream.Dispose();
                }
            }
        }

        /// <summary>
        /// Deserializes workflow markup into an OrderHeaderType object
        /// </summary>
        /// <param name="xml">string workflow markup to deserialize</param>
        /// <param name="obj">Output OrderHeaderType object</param>
        /// <param name="exception">output Exception value if deserialize failed</param>
        /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
        public static bool Deserialize(string xml, out OrderHeaderType obj, out System.Exception exception) {
            exception = null;
            obj = default(OrderHeaderType);
            try {
                obj = Deserialize(xml);
                return true;
            }
            catch (System.Exception ex) {
                exception = ex;
                return false;
            }
        }

        public static bool Deserialize(string xml, out OrderHeaderType obj) {
            System.Exception exception = null;
            return Deserialize(xml, out obj, out exception);
        }

        public static OrderHeaderType Deserialize(string xml) {
            System.IO.StringReader stringReader = null;
            try {
                stringReader = new System.IO.StringReader(xml);
                return ((OrderHeaderType)(Serializer.Deserialize(System.Xml.XmlReader.Create(stringReader))));
            }
            finally {
                if ((stringReader != null)) {
                    stringReader.Dispose();
                }
            }
        }

        }

        /// <summary>
        /// Deserializes xml markup from file into an OrderHeaderType object
        /// </summary>
        /// <param name="fileName">string xml file to load and deserialize</param>
        /// <param name="obj">Output OrderHeaderType object</param>
        /// <param name="exception">output Exception value if deserialize failed</param>
        /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
        public static bool LoadFromFile(string fileName, out OrderHeaderType obj, out System.Exception exception) {
            exception = null;
            obj = default(OrderHeaderType);
            try {
                obj = LoadFromFile(fileName);
                return true;
            }
            catch (System.Exception ex) {
                exception = ex;
                return false;
            }
        }

        public static bool LoadFromFile(string fileName, out OrderHeaderType obj) {
            System.Exception exception = null;
            return LoadFromFile(fileName, out obj, out exception);
        }

        public static OrderHeaderType LoadFromFile(string fileName) {
            System.IO.FileStream file = null;
            System.IO.StreamReader sr = null;
            try {
                file = new System.IO.FileStream(fileName, FileMode.Open, FileAccess.Read);
                sr = new System.IO.StreamReader(file);
                string xmlString = sr.ReadToEnd();
                sr.Close();
                file.Close();
                return Deserialize(xmlString);
            }
            finally {
                if ((file != null)) {
                    file.Dispose();
                }
                if ((sr != null)) {
                    sr.Dispose();
                }
            }
        }
        #endregion
    }

2 个答案:

答案 0 :(得分:0)

如果您的用户提供的文档未针对架构进行验证,则XSD2Code可能会遇到问题。把它扔回用户并告诉他们修复它。或者解析文档并自行解释,这样您就可以编写自己的代码来决定如何从可疑案例中恢复。

如果文档确实对模式进行了验证,但XSD2Code无法处理它,请向XSD2Code的作者投诉并修复它,或者将其替换为没有相同错误/限制的内容。这可能意味着编写自己的代码。

如果XSD2Code可以处理它,但C#提供的代码不能处理它,你需要去寻找可以处理它的代码(建议使用websearch:c#parse iso 8601),或者编写自己的代码。

答案 1 :(得分:0)

我完成了一些事情,

  1. 我使用了一个重构工具将生成的类中的所有DateTime更改为字符串,并以一种方式编写代码,就好像DateTime是一个字符串一样。 (虽然这可能不是最佳的,但它有效!)
  2. 询问生成xml的人修复生成的xml文件。所以当/如果我得到一个新文件,我可以从XSD重新生成类并按预期使用DateTime字段。
  3. 虽然使用字符串编写这个问题不是最好的事情,但它应该以任何方式工作,直到我得到一个正确处理的文件我将使用重构工具将所有DateTime更改为字符串。