2014-01-02 5 views
0

У меня есть сторонний XML-файл, который мне нужно десериализовать в объекты, но когда я это сделаю, я получаю сообщение об ошибке: string was not recognized as a valid datetime. Это связано с тем, что время в XML - это просто время, в формате HH:mm:SS и классы, которые были сгенерированы из XSD у третьего лица, производят поле datetime, которое ожидает время даты, а не только время.Deserializing XML time to datetime?

они дают мне XML:

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

сгенерированный класс создает System.DateTime объекта для хранения десериализованного PurchaseOrderTime но терпит неудачу из-за него, ожидая формат по линии yyyy/MM/dd HH:mm:SS tt, но как я не имею никакого контроля над тем, что они отправляют мне xsd или xml, что я могу сделать, чтобы исправить это?

Есть ли способ предварительной обработки поля, чтобы получить то, что мне нужно?

ли я вручную изменить System.DateTimetimespan к (там больше, чем просто в этот раз поле в противном случае я бы просто сделал это)

Что такое лучший способ сделать это?

Edit 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 
    } 
+0

Как вы десериализируете XML? – MarcinJuraszek

+0

Я использовал XSD2Code для генерации классов из xml, и это «автоматически» добавляет методы сериализации и десериализации, которые вскоре изменят вопрос с помощью методов. – Archangel33

ответ

0

я в конечном итоге делает несколько вещей,

  1. Я использовал инструмент рефакторинга, чтобы изменить все DateTime с в сгенерированных классов строк и написал код таким образом, что он будет работать, как если бы в DateTime была строка. (хотя это может быть не оптимальным, это работает!)
  2. Спросил людей, которые сгенерировали xml, чтобы исправить сгенерированный XML-файл. так что когда/если я получу новый файл, я могу просто восстановить классы из XSD и использовать поля DateTime, как и ожидалось.

Хотя программирующий вокруг этого вопроса со строками не самое лучшее, он должен работать в любом случае, и пока я не получить файл, который обрабатывает правильно, я просто использовать инструмент рефакторинга, чтобы изменить все DateTime «S в строки.

0

Если пользователь дает вам документ, который не проверяет против схемы, XSD2Code, скорее всего, возникнут проблемы с ним. Бросьте его обратно на пользователя и скажите им, чтобы он исправил это. Или проанализируйте документ и интерпретируйте его самостоятельно, чтобы вы могли написать свой собственный код, чтобы решить, как оправиться от сомнительных случаев.

Если документ действительно относится к схеме, но XSD2Code не может его обработать, обратитесь к авторам XSD2Code и исправьте его или замените его тем, что не имеет такой же ошибки/ограничения. Что еще может означать написание собственного кода.

Если XSD2Code может обрабатывать его, но код предоставленного C# не может, вам нужно либо искать код, который может его обрабатывать (предлагаемый websearch: C# parse iso 8601), либо написать свой собственный.

+0

XML выполняет проверку подлинности XSD. Это просто, что C# не нравится формат, в который входит время.Мне жаль, что они не были пользователями, и я мог бы сказать им, чтобы они только исправили это, но это те, которые диктуют, что такое XML и XSD, в этом случае я пользователь. – Archangel33

+0

Является ли ваша проблема генерированием кода XSD2Code ожидаемым диапазоном синтаксиса даты/времени [ISO 8601] (http://www.w3.org/TR/NOTE-datetime) или что класс C# datetime не делает этого? Если первое, вам нужно взять его с людьми, которые написали XSD2Code. Хотя они могут обвинить его в последнем. Если последнее, вам или им нужно найти или написать рутину, которая может справиться с этим. – keshlam

+0

Это последний, класс C# datetime не принимает ожидаемый формат времени. – Archangel33