Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Prism XMLSerializer: Verschachtelte XML-Dateien mit Arrays? (https://www.delphipraxis.net/83987-xmlserializer-verschachtelte-xml-dateien-mit-arrays.html)

Alexander 9. Jan 2007 19:21


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:
<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>
Das ist jetzt irgendeine XML-Struktur, die ich mir gerade mal so ausgedacht habe. Wie sinnvoll das nun ist, spielt jetzt mal keine Rolle :).
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

Elvis 9. Jan 2007 20:39

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? ;)

Khabarakh 9. Jan 2007 20:40

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
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?

So flexibel, dass du (naja, fast :zwinker: ) jedes XML-Schema in xsd.exe werfen kannst und dann einen fertigen Quelltext zurückbekommst, dessen Klassen sich genau nach jenem Schema serialisieren lassen ;) . Dein Beispiel sollte sich also buchstäblich in Klassen, die genau diesen XML-Code generieren, umsetzen lassen.

Alexander 10. Jan 2007 17:41

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

Alexander 10. Jan 2007 17:57

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:

Alexander 12. Jan 2007 18:22

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?

Alexander 2. Feb 2007 14:43

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 :)

Elvis 4. Feb 2007 20:17

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Da gibt es doch sicherlich eine einfache Möglichkeit, oder?

Dich hätte ich fast vergessen...

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;

Alexander 5. Feb 2007 16:01

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:
  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;
Jetzt müsste ich deinen Code nehmen, einbinden und im Code String durch CData ersetzen und "schon" klappt es?
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?

Elvis 5. Feb 2007 19:20

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Jetzt müsste ich deinen Code nehmen, einbinden und im Code String durch CData ersetzen und "schon" klappt es?
Das wäre ja einfach.

Exakt! :)
Delphi-Quellcode:
Wäre, weil ich leider deinen Code nicht nach Delphi konvertiert bekomme. Vielleicht kannst du mir da noch helfen?
Er benutzt halt .Net 2.0, ich dachte du würdest einfach die generischen Interfaces rausnehmen und den rest zu DfN konvertiert kriegen.
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:

Wird beim Serialisieren WriteXml aufgerufen?
Jupp, das ist der Teil, der IXmlSerializable implementiert. ;)
Zitat:

Eine Möglichkeit ähnlich der Serialisierung von ArrayListen o.ä. gibt es nicht, oder?
Nein, einer der Beta Builds von .Net 2.0 hatte es, aber die Hirnies aus Redmond haben es bis zur Final wieder entfernt.

Elvis 5. Feb 2007 22:23

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hab' mir doch etwas Zeit gelassen.
Ich habe ein Archiv mit der Klasse und 2 Kompilaten (1.1 und 2.0) angehängt.

Falls du es selbst kompilieren willst:
Als Compiler empfehle ich dir die Mono version (hier ganz unten, da sie einfach als tar ball kommt, den du nur irgendwohin entpacken musst.
Kompiliert wird für jeweils eine bestimmte .Net Version so:
Code:
chrome.exe SampleLib.chrome /frameworkversion=v1.1.4322 out=1.1
chrome.exe SampleLib.chrome /frameworkversion=v2.0.50727 out=2.0

Alexander 6. Feb 2007 12:47

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Cool Danke, Robert!

Ich werde mir das nachher zu Hause mal in Ruhe anschauen.

Nachtrag:
Im Prinzip hatte ich es so eigentlich auch. Nur konnte Delphi merkwürdiger Weise nicht von IXmlSerializable ableiten :stupid:.
Ich werde es nachher noch mal probieren. Oder noch besser lasse es einfach sein und nehme für so was wirklich den Chrome- oder C#-Compiler ;).

Elvis 6. Feb 2007 17:28

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Cool Danke, Robert!

Kein Problem. ;)
Zitat:

Oder noch besser lasse es einfach sein und nehme für so was wirklich den Chrome- oder C#-Compiler ;).
Kann ich nur empfehlen...

Alexander 6. Feb 2007 18:57

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Ich habe jetzt einfach mal zum Testen deine fertige Lib verwendet.
Und es scheint zur Hälfte zu funktionieren :).
In der XML-Datei soll ein SQL-Statement abgespeichert werden. Dieses wird gleich am Anfang an eine (Fremd-) Komponente (Win32, ActiveX) weitergegeben. Theoretisch mit dem CDATA-Abschnitt ja kein Problem.
Bisher habe ich zum Testen ohne CDATA gearbeitet - hat mit der Komponente funktioniert. Um die gleichen SQL-Statements habe ich nun ein <![CDATA[ und ein ]]> geschrieben.
Dann das Object (CData statt String) angepasst und *wuppdi* hätte es funktionieren müssen.

Die verwendete Komponente sagt mir den folgenden Fehler:
Zitat:

Die SELECT-Anweisung schließt ein reserviertes Wort oder einen Argumentnamen ein, das/der falsch, mit falscher Zeichensetzung oder überhaupt nicht eingegeben wurde.
[ODBC Error] SQLSTATE=37000]
Das verwendete Statement ist eigentlich richtig (aus der XML eingelesen):
SQL-Code:
---------------------------

---------------------------
 SELECT Artikel.[Artikel-Nr], Artikel.Artikelname, Artikel.[Lieferanten-Nr], Artikel.Lagerbestand FROM Artikel ORDER BY Artikel.[Artikel-Nr] where (Artikel.[Artikel-Nr] between 1 and 10)
---------------------------
OK  
---------------------------
Genau dieses Statement hat zu vor funktioniert.

Kann es sein, dass die Komponente irgendwelche Codierungen verwechselt? Hast du eine Idee, woran das liegen könnte?

Besten Dank nochmals,
Alexander

Elvis 6. Feb 2007 19:13

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Ich habe jetzt einfach mal zum Testen deine fertige Lib verwendet.

Der solltest du aber noch deinen Namespace[1] verpassen und sie dann neu kompostieren. ClassLib1 sieht komisch aus. ;)
Zitat:

Kann es sein, dass die Komponente irgendwelche Codierungen verwechselt? Hast du eine Idee, woran das liegen könnte?
Ohne den Code, mit dem du es an die Komponente übergeben hast, wird das etwas schwer.
Sehr dumm ist es, wenn die Komponente ein Object schluckt und dann einfach anhand des Typen irgendwas friemelt. Deshalb würde ich einen Cast auf String empfehlen.
Außerdem ist es nicht dumm der XML Datei ein Unicode-Format zu geben um Konvertierungsprobleme gleich von Anfang an auszuschließen.

Es ist leider nicht möglich den inneren Text öffentlich zugänglich zu machen ohne Inkonsistenzen zu riskieren.
CData muss als primitiver Typ auftreten, auch wenn es eigentlich nur ein Wrapper um einen String ist.

btw: Diese eckigen Klammern gibt es eigentlich nur in den beiden komischen Accessversionen, die Microsoft DBMS nennt: Dem serverbasierten Access namens SqlServer und dem clientbasierten Access namens Jet/Access. :mrgreen:
Bei einen richtigen/normalen DBMS werden Bezeichner, die gegen die Regeln normaler Bezeichner des DBMS verstoßen, in Anführungszeichen ( #34 ) eingeschlossen. Wobei die Bezeichner dann auch case sensitive sind!

[1]der Teil vor dem letzten Punkt in deinen Unitnamen, DfN-Namespaces sind, höflich ausgedrückt, komisch

Alexander 6. Feb 2007 19:26

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Elvis
Zitat:

Zitat von Alexander
Ich habe jetzt einfach mal zum Testen deine fertige Lib verwendet.

Der solltest du aber noch deinen Namespace[1] verpassen und sie dann neu kompostieren. ClassLib1 sieht komisch aus. ;)

Na klar, war ja nur zum Testen.
Zitat:

Zitat:

Kann es sein, dass die Komponente irgendwelche Codierungen verwechselt? Hast du eine Idee, woran das liegen könnte?
Ohne den Code, mit dem du es an die Komponente übergeben hast, wird das etwas schwer.
Sehr dumm ist es, wenn die Komponente ein Object schluckt und dann einfach anhand des Typen irgendwas friemelt. Deshalb würde ich einen Cast auf String empfehlen.
Ist eigentlich zumindest, nach dem was Delphi anzeigt, ein string. (Gibt es eigentlich einen Unterschied zwischen string und String? Oder wird das string auf String gemappt, oder umgekehrt?)
Zitat:

Außerdem ist es nicht dumm der XML Datei ein Unicode-Format zu geben um Konvertierungsprobleme gleich von Anfang an auszuschließen.
Ist ein Utf-8-Format (<?xml version="1.0" encoding="utf-8"?>)

Zitat:

Zitat:

Es ist leider nicht möglich den inneren Text öffentlich zugänglich zu machen ohne Inkonsistenzen zu riskieren.
CData muss als primitiver Typ auftreten, auch wenn es eigentlich nur ein Wrapper um einen String ist.
btw: Diese eckigen Klammern gibt es eigentlich nur in den beiden komischen Accessversionen, die Microsoft DBMS nennt: Dem serverbasierten Access namens SqlServer und dem clientbasierten Access namens Jet/Access. :mrgreen:
Bei einen richtigen/normalen DBMS werden Bezeichner, die gegen die Regeln normaler Bezeichner des DBMS verstoßen, in Anführungszeichen ( #34 ) eingeschlossen. Wobei die Bezeichner dann auch case sensitive sind!
Jupp, ist Access ;). Aber auch nur weil ich da die nwind Datenbank als Testdatenbank nehme. Ich muss die Komponente auch noch mal zu ADO.NET überreden ;).


Nachtrag:
Zum Source: Die Lade und Speicher Methode und ein Test-Object stehen ja oben schon.
Und so setze ich einfach das SQL-Statement:
Delphi-Quellcode:
    Cube.DCRecordSource := aStatement.Sql;
Das war's im Prinzip.

Elvis 6. Feb 2007 20:24

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
st eigentlich zumindest, nach dem was Delphi anzeigt, ein string.

Dann sollte es keine Probleme geben. CData kann sich implizit in einen String wandeln indem es einfach Text zurückgibt.

Zitat:

Gibt es eigentlich einen Unterschied zwischen string und String?
Ja gibt es, zumindest syntaktisch. In Delphi.Net kannst du keine Member von String benutzen, außer du nimmst einen typecast auf System.String, bzw. deklarierst ihn so. :freak:
Zitat:

Oder wird das string auf String gemappt, oder umgekehrt?
Da kennt wohl einer Reflector noch nicht? :warn:

Wirkliche Klarheit wird dir nur der Debugger liefern können. Einfach mal schauen, was in CData drin steht.
Da CData ToString überschreibt sollte der Inhalt zu sehen sein ohne es aufklappen zu müssen. :)

Alexander 7. Feb 2007 08:42

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Ich habe es jetzt noch mal mit dem Chrome-Compiler neu kompiliert (nun auch mit nem ordentlichen Namespace).

Zitat:

Zitat von Elvis
Zitat:

Zitat von Alexander
st eigentlich zumindest, nach dem was Delphi anzeigt, ein string.

Dann sollte es keine Probleme geben. CData kann sich implizit in einen String wandeln indem es einfach Text zurückgibt.

Das habe ich mir ja auch gedacht. Es gibt einfach keinen Unterschied. Dennoch meckert die Komponente.

Zitat:

Zitat:

Gibt es eigentlich einen Unterschied zwischen string und String?
Ja gibt es, zumindest syntaktisch. In Delphi.Net kannst du keine Member von String benutzen, außer du nimmst einen typecast auf System.String, bzw. deklarierst ihn so. :freak:
Zitat:

Oder wird das string auf String gemappt, oder umgekehrt?
Da kennt wohl einer Reflector noch nicht? :warn:
Ehrlich gesagt, nicht wirklich. Bei der geringen Zeit, die ich momentan habe :sad:.
(Hast du dir dein Wissen eigentlich selbst beigebracht? )


Zitat:

Wirkliche Klarheit wird dir nur der Debugger liefern können. Einfach mal schauen, was in CData drin steht.
Da CData ToString überschreibt sollte der Inhalt zu sehen sein ohne es aufklappen zu müssen. :)
Leider ja auch nicht. Hatte ich ja schon versucht. Der SQL-String wird komplett richtig ausgelesen. Auch die Komponente hat den eigentlich den richtigen String bekommen. Nur irgendetwas scheint zu stören und es kommt zum Fehler.

Es handelt sich im Übrigen um diese Komponente:
http://www.datadynamics.com/Products...spx?Product=DC
Allerdings in einer etwas älteren Version (2.5).

Elvis 7. Feb 2007 10:44

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Zitat:

Da kennt wohl einer Reflector noch nicht? :warn:
Ehrlich gesagt, nicht wirklich. Bei der geringen Zeit, die ich momentan habe :sad:.

Reflector spart Zeit, damit kannst du durch deine und fremde Binaries surfen wie ein einem Browser. :)
Zitat:

(Hast du dir dein Wissen eigentlich selbst beigebracht? )
Steht ja genug im Internet, und ich habe einen gesunden (kranken?) Spieltrieb. ;)

Zitat:

Leider ja auch nicht. Hatte ich ja schon versucht. Der SQL-String wird komplett richtig ausgelesen. Auch die Komponente hat den eigentlich den richtigen String bekommen. Nur irgendetwas scheint zu stören und es kommt zum Fehler.
Kann es sein, dass Jet zu blöd ist um einen einzelnen line feed (#10) als Zeilenumbruch/Whitespace anzusehen?
Denn bei einem Zeilenumbruch geht definitiv der Cr (#13) flöten, wenn man nicht explizit über einen XmlReader deserialisiert...
Hier mal zur Anschauung
Delphi-Quellcode:
type
  SampleClass = public class
  public
    property CDataString : CData;  
  end;

class method ConsoleApp.Main;
  const fileName    = 'data.xml';
  const sampleString = 'SELECT A, B'#13#10
                       'FROM  C';
 
  method ShowWhiteSpaces(value : String);
  begin
    Console.WriteLine(value.Replace(#32,   '[Space]')
                           .Replace(#9,    '[Tab]')
                           .Replace(#13#10, '[CrLf]')
                           .Replace(#13,   '[Cr]')
                           .Replace(#10,   '[Lf]'));
  end;
begin
  var serializer := new XmlSerializer(typeof(SampleClass));
 
  if not File.Exists(fileName) then
    using stream := new FileStream(fileName, FileMode.Create) do
    using writer := new XmlTextWriter(stream, Encoding.UTF8) do
    begin
      serializer.Serialize(writer, new SampleClass(CDataString := sampleString));
    end;
 
  // mit reader        
  using stream := new FileStream(fileName, FileMode.Open) do
  using reader := new XmlTextReader(stream) do
    with s := serializer.Deserialize(reader) as SampleClass do
      ShowWhiteSpaces(s.CDataString);            
 
  // ohne reader
  using stream := new FileStream(fileName, FileMode.Open) do
    with s := serializer.Deserialize(stream) as SampleClass do
      ShowWhiteSpaces(s.CDataString);            
       
  Console.ReadLine();  
end;
Interessant ist was dabei rauskommt:
Output
SELECT[Space]A,[Space]B[CrLf]FROM[Space][Space][Space]C
SELECT[Space]A,[Space]B[Lf]FROM[Space][Space][Space]C
Wie du siehst verhält sich der Overload von DeSerialize, der einen Stream schluckt, nicht wie es ein XmlReader per default macht. :?

Alexander 7. Feb 2007 14:37

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Das war's auch nicht.
Es sind keine lf's, tabs etc. im String drin. Leider :sad:.

Ich habe gerade mal versucht, das SQL-Statement mit beiden Varianten auszulesen, um den String vergleichen zu können.
Delphi-Quellcode:
  TStatement = class
  public
    Connection : TDataBaseConnection;
    [XmlElement('Sql')]
    Sql2 : String;
    Sql : CDataLib.CData;
  end;
Leider bekomme ich da zur Laufzeit einen Fehler:
Zitat:

Projekt dynCubes.exe traf auf die unhandelte Exception-Klasse System.InvalidOperationException mit der Meldung 'Fehler beim Reflektieren des Typs 'dataReader.TControllingData'.'.
Und zwar kommt die Exception so bald der Serializer erzeugt wird:
Delphi-Quellcode:
  Ser := XmlSerializer.Create(typeOf(TData));
(TStatement taucht in TData wieder auf).

Ist das nicht möglich oder bin ich da auf dem Holzweg?

Elvis 7. Feb 2007 14:46

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Leider bekomme ich da zur Laufzeit einen Fehler:
Zitat:

Projekt dynCubes.exe traf auf die unhandelte Exception-Klasse System.InvalidOperationException mit der Meldung 'Fehler beim Reflektieren des Typs 'dataReader.TControllingData'.'.
Und zwar kommt die Exception so bald der Serializer erzeugt wird:
Delphi-Quellcode:
  Ser := XmlSerializer.Create(typeOf(TData));
(TStatement taucht in TData wieder auf).
Ist das nicht möglich oder bin ich da auf dem Holzweg?

Ich habe absolut keinen Plan was da passiert, da du einfach nicht genug Code rausrückst. ;)
Aber als Randbemerkung: Es ist ziemlich böse dem Serializer öffentliche Felder vorzuwerfen, vor allem wenn diese Felder Collections sind.


edit: Du hast 2-mal das gleiche Element! Sql und Sql2 sind beide das Element Sql. Das ist nicht erlaubt.

Alexander 7. Feb 2007 16:40

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

edit: Du hast 2-mal das gleiche Element! Sql und Sql2 sind beide das Element Sql. Das ist nicht erlaubt.
Schade. Ich habe jetzt einfach mal 2 mal deserialisiert. Einmal mit String und einmal mit deinem CDATA-Object und dann mittels Equals verglichen.
Beide Strings sind 100% identisch. Auf der einen Seite verwundertlich, auf der anderen wieder um nicht.

Es liegt also scheinbar nicht an der Art des Deserialisierens, sondern an etwas anderem. Die große Frage ist nur noch, an was :zwinker:

Zitat:

Zitat von Elvis
Ich habe absolut keinen Plan was da passiert, da du einfach nicht genug Code rausrückst. ;)

Tja, ich habe eigentlich alles mehr oder weniger schon gepostet.
Aber ich hänge die komplette Unit noch mit einer XML-Datei an. Vielleicht kannst du ja noch mal ein Blick reinwerfen.
Ich sehe beim besten Willen den Fehler nicht.

Zitat:

Aber als Randbemerkung: Es ist ziemlich böse dem Serializer öffentliche Felder vorzuwerfen, vor allem wenn diese Felder Collections sind.
Oh. Stimmt, das wollte ich ja noch ändern. Kommt noch vom testen.

Nachtrag:
Zur Erklärung des Codes:
Die verwendete Komponente ist eine Art Grid Komponente. Das SQL-Statement, die Verbindung und die Verteilung der Spalten etc. stehen in der XML-Datei (DAT). Es soll alles ausgelesen und der Komponente übergeben werden.
Hört sich einfach an, ist es ja eigentlich auch, nur macht die Komponente ja scheinbar was es will.
Debuggen bringt nichts. Wenn ich mir den RecordSource (SQL-Text) in der Komponente anschaue, steht dort exakt das, was auch in der XML-Datei steht....

Alexander 11. Feb 2007 17:05

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Ich habe das ganze jetzt noch mal komplett mit Chrome ausprobiert. Da funktioniert es genau so wie es soll.

Scheint wohl ein Bug zu sein :wall: .

Sind vielleicht Chrome Assemblies nicht 100%zig mit Delphi kompatibel?
Kann ich mir allerdings nicht vorstellen (ist ja auch nur CLR).

Elvis 11. Feb 2007 18:14

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Ich habe das ganze jetzt noch mal komplett mit Chrome ausprobiert. Da funktioniert es genau so wie es soll.
Scheint wohl ein Bug zu sein :wall: .

Muss kein Bug in Delphi sein, kann auch einer in .Net 1.1 sein.
Wenn es geht ist doch gut, du kannst die Chrome-Lib ja später per ILMerge zu deinem Delphi Binary ranklatschen.
Zitat:

Sind vielleicht Chrome Assemblies nicht 100%zig mit Delphi kompatibel?
Kann ich mir allerdings nicht vorstellen (ist ja auch nur CLR).
Du dürftest keinen Unterschied zu einer C#-compiled Assembly entdecken können. Außer du weißt genau wonach du suchen musst. :zwinker:
Ich mus aber zugeben, dass ich die Lib nur mit PE Verify von 2.0 getestet habe. Das ist normalerweise viel genauer als das aus 1.1 und da ich nur die mscorelib von 1.1 nahm, hätte e mir auch gezeigt ob ich Dinge aus 2.0 benutze.

Alexander 11. Feb 2007 18:44

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Elvis
Muss kein Bug in Delphi sein, kann auch einer in .Net 1.1 sein.

Stimmt schon.
Zitat:

Wenn es geht ist doch gut, du kannst die Chrome-Lib ja später per ILMerge zu deinem Delphi Binary ranklatschen.
Welche meinst du? Die von dir oder die, die ich jetzt mit zum Testen erstellt habe? ILMerge muss ich mir erstmal anschauen. Kannte ich bisher nicht :zwinker:.
Noch weiß ich nicht genau, was es mir bringt, dass es unter Chrome klappt :lol:. Ich könnte die gesamte Klasse nach Chrome portieren und dann in Delphi einbinden. Oder das gesamte Projekt (so wie du es in dem anderen Thread vorgeschlagen hast) als Lib in Chrome einbinden.
Mal schauen.

Alexander 18. Feb 2007 13:32

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Hallo :)
ich bin nun dazu gekommen, die gesamte Klasse, in der ich die XML-Daten lade, speichere und verwende nach Chrome zu portieren.
Dann mit dem Mono Compiler compiliert und in Delphi.NET eingebunden.
Gleicher Fehler :sad:.
Ich werde das Projekt wohl erstmal in Delphi weiter entwickeln müssen, da sich das mit dem Erwerb von Chrome wohl etwas in die Länge zieht (meine Bank kann leider nichts mit von RemObjects angegebenen ABA- und LLC-Nummer anfangen, ich auch nicht :mrgreen:. Meine Bank braucht unbedingt ne IBAN/BIC Nummer -> Remobjects sagt: Die angegebene Nummern würden reichen :wall:).

Elvis 18. Feb 2007 13:39

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Alexander
Remobjects sagt: Die angegebene Nummern würden reichen :wall:).

Wenn du mit remobjects support@ oder sales@ meinst hattest du wahrscheinlich "nur" einen der sales guys dran.
Frage es direkt in remobjects.non-tech oder remobjects.public.chrome.
Dort wird dann Marc drüber stolpern und er regelt solche Dinge sehr unbürokratisch. (Ist ja auch seine Kohle, die du loswerden willst. :mrgreen: )

Alexander 18. Feb 2007 14:16

Re: XMLSerializer: Verschachtelte XML-Dateien mit Arrays?
 
Zitat:

Zitat von Elvis
Wenn du mit remobjects support@ oder sales@ meinst hattest du wahrscheinlich "nur" einen der sales guys dran.

So war es :mrgreen:.
Danke für den Tip :zwinker: .


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz