none
TimeSpan zu XML serialisieren RRS feed

  • Frage

  • Hallo,

    Ich habe eine Klasse Namen Situation die eine Eigenschaft "Boardingtime as Timespan" besitzt.

    Nun möchte ich die Werte der Klasse per:

     Using sw As New IO.StreamWriter(Situationspfad)
    
            Dim xser As New Xml.Serialization.XmlSerializer(GetType(List(Of Situation)))
            xser.Serialize(sw, Liste_Situationen)
            
          End Using

    Als XML abspeichern.

    er Speichert alles Auch richtig ab nur der Wert BoardingTime bleibt leer.

    Mache ich was falsch ?

     

     

    Gruß Daniel

    Samstag, 4. September 2010 11:34

Antworten

  • Hallo Daniel,

    TimeStamp hat man weggelassen, weil es kein identisches Äquivalent in Xml gibt.
    Eine Lösung dafür zeigt (in C#) XmlSerializer Doesn't Serialize TimeSpan to XML Duration Type

    Auf Visual Basic angepasst und ein kleinig aufgehübscht könnte das wie folgt aussehen:

    Imports System.ComponentModel
    Imports System.Xml
    Imports System.Xml.Serialization
    
    Public Class Situation
      Public Property Name As String
    
      <XmlIgnore()> _
      Public Property Boardingtime As TimeSpan
    
      <XmlElement("Boardingtime", DataType:="duration")> _
      <System.ComponentModel.DefaultValue("PT10M")> _
      <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _
      Public Property XmlBoardingtime As String
        Get
          Return XmlConvert.ToString(Me.Boardingtime)
        End Get
        Set(ByVal value As String)
          If Not String.IsNullOrEmpty(value) Then
            Me.Boardingtime = XmlConvert.ToTimeSpan(value)
          Else
            Me.Boardingtime = TimeSpan.Zero
          End If
        End Set
      End Property
    
      Public Shared Sub Serialize()
        Dim list As New List(Of Situation)
    
        list.Add(New Situation() With {.Name = "Wichtig", .Boardingtime = New TimeSpan(1, 2, 3)})
        list.Add(New Situation() With {.Name = "Ohne Zeit"})
        Using sw As New IO.StreamWriter("C:\TEMP\Situation.xml")
          Dim xser As New Xml.Serialization.XmlSerializer(GetType(List(Of Situation)))
          xser.Serialize(sw, list)
        End Using
    
        Dim newList As List(Of Situation)
        Using sw As New IO.StreamReader("C:\TEMP\Situation.xml")
          Dim xser As New Xml.Serialization.XmlSerializer(GetType(List(Of Situation)))
          newList = DirectCast(xser.Deserialize(sw), List(Of Situation))
        End Using
        For Each item In newList
          Console.WriteLine("{0} {1}", item.Name, item.Boardingtime)
        Next
      End Sub
    End Class
    

    Gruß Elmar

    • Bearbeitet Elmar Boye Samstag, 4. September 2010 14:06 Format
    • Als Antwort markiert B00NE Samstag, 4. September 2010 22:26
    • Tag als Antwort aufgehoben B00NE Samstag, 4. September 2010 22:29
    • Als Antwort markiert B00NE Samstag, 4. September 2010 22:29
    • Tag als Antwort aufgehoben B00NE Samstag, 4. September 2010 22:53
    • Als Antwort markiert B00NE Sonntag, 5. September 2010 17:17
    Samstag, 4. September 2010 14:04
  • Hallo Daniel,

    dass meine Methode oben direkt in der Klasse definiert ist, macht keinen Unterschied.

    Solltest Du allerdings "D uration" anstatt "d uration" verwendet haben,
    wie ich nach dem Ausnahmetext vermute:                     

    Message=Der Wert 'Duration' kann nicht für die Eigenschaft 'XmlElementAttribute.DataType' verwendet werden.
    Der Datentyp 'http://www.w3.org/2001/XMLSchema:Duration' ist nicht vorhanden.

    so spielt das durchaus eine Rolle, denn die Angabe ist muß exakt so geschrieben werden,
    siehe  XmlElementAttribute. DataType (aber auch alle anderen Xml...DataTypes).
    Die Xml-Spezifikation ist nunmal von Java-Liebhabern geschrieben worden ;-)

    Gruß Elmar

    • Als Antwort markiert B00NE Sonntag, 5. September 2010 17:17
    Sonntag, 5. September 2010 08:15

Alle Antworten

  • Hallo Daniel,

    TimeStamp hat man weggelassen, weil es kein identisches Äquivalent in Xml gibt.
    Eine Lösung dafür zeigt (in C#) XmlSerializer Doesn't Serialize TimeSpan to XML Duration Type

    Auf Visual Basic angepasst und ein kleinig aufgehübscht könnte das wie folgt aussehen:

    Imports System.ComponentModel
    Imports System.Xml
    Imports System.Xml.Serialization
    
    Public Class Situation
      Public Property Name As String
    
      <XmlIgnore()> _
      Public Property Boardingtime As TimeSpan
    
      <XmlElement("Boardingtime", DataType:="duration")> _
      <System.ComponentModel.DefaultValue("PT10M")> _
      <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _
      Public Property XmlBoardingtime As String
        Get
          Return XmlConvert.ToString(Me.Boardingtime)
        End Get
        Set(ByVal value As String)
          If Not String.IsNullOrEmpty(value) Then
            Me.Boardingtime = XmlConvert.ToTimeSpan(value)
          Else
            Me.Boardingtime = TimeSpan.Zero
          End If
        End Set
      End Property
    
      Public Shared Sub Serialize()
        Dim list As New List(Of Situation)
    
        list.Add(New Situation() With {.Name = "Wichtig", .Boardingtime = New TimeSpan(1, 2, 3)})
        list.Add(New Situation() With {.Name = "Ohne Zeit"})
        Using sw As New IO.StreamWriter("C:\TEMP\Situation.xml")
          Dim xser As New Xml.Serialization.XmlSerializer(GetType(List(Of Situation)))
          xser.Serialize(sw, list)
        End Using
    
        Dim newList As List(Of Situation)
        Using sw As New IO.StreamReader("C:\TEMP\Situation.xml")
          Dim xser As New Xml.Serialization.XmlSerializer(GetType(List(Of Situation)))
          newList = DirectCast(xser.Deserialize(sw), List(Of Situation))
        End Using
        For Each item In newList
          Console.WriteLine("{0} {1}", item.Name, item.Boardingtime)
        Next
      End Sub
    End Class
    

    Gruß Elmar

    • Bearbeitet Elmar Boye Samstag, 4. September 2010 14:06 Format
    • Als Antwort markiert B00NE Samstag, 4. September 2010 22:26
    • Tag als Antwort aufgehoben B00NE Samstag, 4. September 2010 22:29
    • Als Antwort markiert B00NE Samstag, 4. September 2010 22:29
    • Tag als Antwort aufgehoben B00NE Samstag, 4. September 2010 22:53
    • Als Antwort markiert B00NE Sonntag, 5. September 2010 17:17
    Samstag, 4. September 2010 14:04
  • Hallo Elmar,

     

    Hab den Code genau so gändert wie oben beschrieben, mit den eizigsten Unterschied das ich das Serialisieren ausserhab der Klasse durch führe :

          Using sw As New IO.StreamWriter(Situationspfad)
    
            Dim xser As New Xml.Serialization.XmlSerializer(GetType(List(Of Situation)))
            xser.Serialize(sw, Liste_Situationen)
            Status("Situation gespeichert!")
          End Using

     

    nun bekomme ich in der Zeile "Dim xser as......" aber die Folgende Fehlermeldung

    System.InvalidOperationException wurde nicht behandelt.
      Message=Fehler beim Reflektieren des Typs 'System.Collections.Generic.List`1[FDS.Situation]'.
      Source=System.Xml
      StackTrace:
           bei System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
           bei System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
           bei System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
           bei System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
           bei System.Xml.Serialization.XmlSerializer..ctor(Type type)
           bei FDS.LadenSpeichern.Speichern(LS ls, Boolean Automatisch)
           bei FDS.frmHauptblatt.frmHauptblatt_FormClosing(Object sender, FormClosingEventArgs e)
           bei System.Windows.Forms.Form.OnFormClosing(FormClosingEventArgs e)
           bei System.Windows.Forms.Form.WmClose(Message& m)
           bei System.Windows.Forms.Form.WndProc(Message& m)
           bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           bei System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam)
           bei System.Windows.Forms.Control.SendMessage(Int32 msg, Int32 wparam, Int32 lparam)
           bei System.Windows.Forms.Form.Close()
           bei FDS.frmHauptblatt.BeendenToolStripMenuItem_Click(Object sender, EventArgs e)
           bei System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
           bei System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
           bei System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
           bei System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
           bei System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
           bei System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
           bei System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
           bei System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
           bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           bei System.Windows.Forms.Control.WndProc(Message& m)
           bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
           bei System.Windows.Forms.ToolStrip.WndProc(Message& m)
           bei System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
           bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
           bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           bei System.Windows.Forms.Application.Run(ApplicationContext context)
           bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
           bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
           bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
           bei FDS.My.MyApplication.Main(String[] Args)
           bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
           bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           bei System.Threading.ThreadHelper.ThreadStart()
      InnerException: System.InvalidOperationException
           Message=Fehler beim Reflektieren des Typs 'FDS.Situation'.
           Source=System.Xml
           StackTrace:
                bei System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
                bei System.Xml.Serialization.XmlReflectionImporter.CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArrayItemAttributes attributes, Type arrayElementType, String arrayElementNs, RecursionLimiter limiter)
                bei System.Xml.Serialization.XmlReflectionImporter.ImportArrayLikeMapping(ArrayModel model, String ns, RecursionLimiter limiter)
                bei System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
           InnerException: System.InvalidOperationException
                Message=Fehler beim Reflektieren der Eigenschaft 'XmlBoardingtime'.
                Source=System.Xml
                StackTrace:
                     bei System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
                     bei System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
                     bei System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
                InnerException: System.InvalidOperationException
                     Message=Fehler beim Reflektieren des Typs 'System.String'.
                     Source=System.Xml
                     StackTrace:
                          bei System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
                          bei System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
                          bei System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
                          bei System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
                     InnerException: System.InvalidOperationException
                          Message=Der Wert 'Duration' kann nicht für die Eigenschaft 'XmlElementAttribute.DataType' verwendet werden. Der Datentyp 'http://www.w3.org/2001/XMLSchema:Duration' ist nicht vorhanden.
                          Source=System.Xml
                          StackTrace:
                               bei System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
                          InnerException:

     

    Danke Mühe ...

     

    Daniel

     

     

    Samstag, 4. September 2010 22:29
  • Hallo Daniel,

    dass meine Methode oben direkt in der Klasse definiert ist, macht keinen Unterschied.

    Solltest Du allerdings "D uration" anstatt "d uration" verwendet haben,
    wie ich nach dem Ausnahmetext vermute:                     

    Message=Der Wert 'Duration' kann nicht für die Eigenschaft 'XmlElementAttribute.DataType' verwendet werden.
    Der Datentyp 'http://www.w3.org/2001/XMLSchema:Duration' ist nicht vorhanden.

    so spielt das durchaus eine Rolle, denn die Angabe ist muß exakt so geschrieben werden,
    siehe  XmlElementAttribute. DataType (aber auch alle anderen Xml...DataTypes).
    Die Xml-Spezifikation ist nunmal von Java-Liebhabern geschrieben worden ;-)

    Gruß Elmar

    • Als Antwort markiert B00NE Sonntag, 5. September 2010 17:17
    Sonntag, 5. September 2010 08:15
  • Elmar,

    das war das Problem. was doch so keine Fehler Wie D vs d doch für Auswirkungen haben können;-).

     

    Dank dir für die Hilfe und noch ein schönen Sonntag

     

     

    Gruß Daniel

     

     

     

    Sonntag, 5. September 2010 17:17