Benutzer mit den meisten Antworten
TimeSpan zu XML serialisieren

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
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 TypeAuf 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
-
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
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 TypeAuf 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
-
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
-
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