![]() |
XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Hallo DPler,
ich habe gerade ein wenig über XMLSerializer gelesen und bin zu dem Entschluss gekommen: Das brauche ich! Wie sehr müsste man sich doch abmühen, eine große XML-Datei per Hand über System.XML zu zerpflücken und in eine Klasse zu schieben. Doch klappt Serialisierung auch bei tief verschachtelten XML-Dateien, die zudem noch mit Array's in verschiedenen Ebenen gespickt sind? Sprich wie flexibel ist Serialisierung? Mal ein Beispiel (die Struktur):
XML-Code:
Das ist jetzt irgendeine XML-Struktur, die ich mir gerade mal so ausgedacht habe. Wie sinnvoll das nun ist, spielt jetzt mal keine Rolle :).
<config>
<einstellung1> <foo_1 name="">blupp</foo_1> <foo_2>irgendetwas anderes</foo_2> </einstellung1> <Geoeffnete_Dateien> <datei> <pfad></pfad> <datum></datum> <nocheinArray> <eintrag></eintrag> <eintrag></eintrag> </nocheinArray> </datei> <datei> <pfad></pfad> <datum></datum> <nocheinArray> <eintrag></eintrag> <eintrag></eintrag> </nocheinArray> </datei> </Geoeffnete_Dateien> </config> Allerdings stehe ich gerade auf dem Schlauch, den Source Code zu schreiben, der solch eine XML-Struktur erzeugt. Könnt ihr mir da auf die Sprünge helfen? CDATA-Abschnitte und Attribute werden doch sicherlich auch unterstützt, oder? Sonst kann ich das nämlich vergessen :(. Gut Attribute wäre nicht ganz so wichtig, da könnte man einzelen Nodes von machen, das wäre aber nicht so schick :(. Ich freue mich schon auf eure Unterstützung und probiere der Weil selbst ein wenig rum. Alexander |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
lasse einfach mal XSD.exe darüber laufen um eine xsd-Datei zu kriegen.
Lasse es nochmal darüber laufen, diesmal mit dem schalter /c um Klassen zu bekommen. Diese werden in C# sein, um Delphi Klassen zu kriegen müsstest du ihm sagen wo er den CodeDom findet, da sich der Delphi Compiler nicht vollständig ins Framework installiert. Da habe ich irgendwie keine Lust das jetzt rauszukramen. Eine C# ClassLib zu konsumieren ist ja auch OK, right? ;) |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Zitat:
|
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Ich habe mir gerade mal XSD.exe angeschaut und bin schwer begeistert. Wenn der mir noch Delphi.NET-Source erzeugen würde, wäre es natürlich perfekt.
Gut ich habe den Code noch nicht ausprobiert (gerade kein VS installiert), aber das was ich an C# Code gesehen habe, ist echt :thumb: Was mich besonders beeindruckt, ist dass es mit xsd.exe noch einfacher ist als ich eh schon dachte (bzw. vermutete). Jetzt muss man sich nicht mal mehr die Klassen zusammenschreiben. Die Schema Datei wird nur zur Erzeugung der Klassen gebraucht, oder? Die verstehe ich nämlich noch nicht ganz. Ich werde zwar sicherlich noch die ein oder andere Frage dazu stellen, möchte mich auf jeden Fall aber schon mal ganz nett bei euch beiden bedanken :P |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Mit dem folgenden Aufruf kann man auch Delphi Code erzeugen:
XSD.exe c:\tt.xsd /l:Borland.Delphi.DelphiCodeProvider,DelphiProvider ,Version=10.0.4143.0,Culture=neutral,PublicKeyToke n=91d62ebb5b0d1b1b /c /o:c:\ Das Staunen steigert sich so langsam noch mehr :mrgreen: |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Soooo jetzt habe ich noch mal ne Frage und zwar möchte ich gerne System.Drawing.Color serialisieren.
Leider wird dabei nichts abgespeichert. Gibt es dabei einen Trick oder soll ich einfach einen String nehmen? und die RGB Werte abspeichern? |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Ich habe dazu noch einmal eine kleine Frage und zwar möchte ich einen String als CDATA Abschnitt speichern / serialisieren.
Leider konnte ich noch nicht herausfinden, wie ich das mit Delphi schaffen kann. Oder soll ich einfach die entsprechende CDATA-Kennzeichnung um den String schmeißen und dann serialisieren (was ich ziemlich unelegant finden würde :?). Da gibt es doch sicherlich eine einfache Möglichkeit, oder? Danke :) |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Zitat:
Du kannst dir ja den Code hier so anpassen dass er mit Delphi.Net oder Chrome/.Net1.1 läuft. Du benutzt einfach die Klasse CData anstatt String und beim Serialisieren bekommst du eine CData section.
Delphi-Quellcode:
uses
System.Xml.*; type CData = public sealed class(IXmlSerializable, IComparable<String>, IEquatable<String>, IComparable<CData>, IEquatable<CData>) public class operator Implicit(value : String) : CData; class operator Implicit(value : CData) : String; class operator Equal(left: CData; right: String) : Boolean; class operator Equal(left: CData; right: CData) : Boolean; method Equals(obj : Object) : Boolean; override; method Equals(obj : CData) : Boolean; implements IEquatable<CData>.Equals; method CompareTo(obj: CData): Integer; implements IComparable<CData>.CompareTo; constructor; empty; constructor(text : String); private method Equals(other: String): Boolean; implements IEquatable<String>.Equals; method CompareTo(other: String): Integer; implements IComparable<String>.CompareTo; Text : String; method WriteXml(writer: XmlWriter); method ReadXml(reader: XmlReader); method GetSchema: XmlSchema; empty; end; implementation constructor CData(text : String); begin self.Text := text; end; method CData.ReadXml(reader: XmlReader); begin Text := reader.ReadString(); end; method CData.WriteXml(writer: XmlWriter); begin writer.WriteCData(Text); end; class operator CData.Implicit(value : String) : CData; begin exit(new CData(value)); end; class operator CData.Implicit(value : CData) : String; begin exit(value.Text); end; method CData.Equals(obj : Object) : Boolean; begin if ReferenceEquals(self, obj) or ReferenceEquals(Text, obj) then exit(true) else if obj is CData then with e := CData(obj) do exit(Equals(e)) else if obj is IEquatable<String> then with e := IEquatable<String>(obj) do exit(e.Equals(Text)) else if obj is IEquatable<CData> then with e := IEquatable<CData>(obj) do exit(e.Equals(self)); end; method CData.Equals(other: String): Boolean; begin exit(Text.Equals(other)); end; method CData.Equals(obj : CData) : Boolean; begin exit(self = obj); end; method CData.CompareTo(other: String): Integer; begin exit(Text.CompareTo(other)); end; method CData.CompareTo(obj: CData): Integer; begin if not assigned(obj) then exit(String.Compare(Text, String(nil))) else exit(String.Compare(Text, obj.Text)) end; class operator CData.Equal(left: CData; right: String) : Boolean; begin if not assigned(left) and not assigned(right) then exit(true) else if not assigned(left) then exit(String.IsNullOrEmpty(right)) else exit(left.Equals(right)); end; class operator CData.Equal(left: CData; right: CData) : Boolean; begin if ReferenceEquals(left, right) then exit(true) else if assigned(left) and assigned(right) then exit(String.Equals(left.Text, right.Text)) else if not assigned(left) then exit(String.Equals(right.Text, String(nil))) else exit(String.Equals(left.Text, String(nil))); end; |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Danke Robert. Aber so ganz habe ich das noch nicht verstanden.
Mal ein Ausschnitt so wie ich es bisher ohne CDATA gemacht habe. Gespeichert wird ein String und eine Arraylist von TFoo.
Delphi-Quellcode:
Jetzt müsste ich deinen Code nehmen, einbinden und im Code String durch CData ersetzen und "schon" klappt es?
TXmlData = class
public test : String; [System.Xml.Serialization.XmlElementAttribute('Foo', TypeOf(TFoo), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] Foo : ArrayList; end; procedure TSteuerdateiReader.saveData; var Ser : XmlSerializer; Writer : StreamWriter; begin Writer := StreamWriter.Create(XmlPath); Ser := XmlSerializer.Create(typeOf(TXmlData)); try Ser.Serialize(Writer, data); finally Writer.Close; Writer.Free; Ser.Free; end; end; procedure TSteuerdateiReader.loadData; var Ser : XmlSerializer; Reader : StreamReader; begin Reader := StreamReader.Create(XmlPath); Ser := XmlSerializer.Create(typeOf(TXmlData)); try data := Ser.Deserialize(Reader) as TXmlData; finally Reader.Close; Reader.Free; Ser.Free; end; end; Das wäre ja einfach. Wäre, weil ich leider deinen Code nicht nach Delphi konvertiert bekomme. Vielleicht kannst du mir da noch helfen? Wird beim Serialisieren WriteXml aufgerufen? Eine Möglichkeit ähnlich der Serialisierung von ArrayListen o.ä. gibt es nicht, oder? |
Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
Zitat:
Delphi-Quellcode:
Er benutzt halt .Net 2.0, ich dachte du würdest einfach die generischen Interfaces rausnehmen und den rest zu DfN konvertiert kriegen.
Wäre, weil ich leider deinen Code nicht nach Delphi konvertiert bekomme. Vielleicht kannst du mir da noch helfen?
No prob, ich bin in etwa 1h zu Hause, dann konvertiere ich es zu Chrome/.Net1.1. Das kannst du ja ganz easy benutzen oder die Syntaxunterschiede selbst übersetzen. (Habe kein DfN ;) ) Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz