![]() |
GraphML, XML Unterschiede im Encoding ?
Liste der Anhänge anzeigen (Anzahl: 3)
ich schreibe mit diesem Code GraphML, XML Dateien :
Delphi-Quellcode:
var
i, j: Integer; const ncnt = 60; var aXMLStreamWriter: TGRAPHMLStreamWriter; h1, h2: string; begin aXMLStreamWriter := TGRAPHMLStreamWriter.Create; try aXMLStreamWriter.AddHeader; aXMLStreamWriter.StartTag('graph'); aXMLStreamWriter.SetAttribute('id', 'G'); aXMLStreamWriter.SetAttribute('edgedefault', 'undirected'); for i := 0 to ncnt do begin aXMLStreamWriter.StartTag('node'); aXMLStreamWriter.SetAttribute('id', 'n' + IntToStr(i)); aXMLStreamWriter.StopTag; end; for i := 0 to ncnt do begin h1 := 'n' + IntToStr(i); h2 := 'n' + IntToStr( ( i +1 ) mod ncnt ); aXMLStreamWriter.StartTag('edge'); aXMLStreamWriter.SetAttribute('source', h1); aXMLStreamWriter.SetAttribute('target', h2); aXMLStreamWriter.StopTag; end; aXMLStreamWriter.StopTag; aXMLStreamWriter.AddFooter; aXMLStreamWriter.SavetoFile('e:\test.graphML'); finally XMLMemo.Lines.Add(aXMLStreamWriter.ToString); XMLMemo.Lines.SavetoFile('e:\test2.graphML'); end; Nur die test2.graphML kann von der Software Graphia ( ![]() Ich vermute der Fehler liegt beim Encoding in meinem Stringstream, habe aber bereits hier UTF-8 ausgewählt. Die Funktionen zum Schreiben der XML Files sind hier : Das lauffähige Projekt und die Beipieldatein in in der Anlage.
Delphi-Quellcode:
type TXMLStreamWriter = class private /// <summary> /// end the current string/TAG with a new line /// </summary> FNewLineWritten: Boolean; FIsStartTagClosed: Boolean; FStream: TStringStream; FTagStack: TStringStack; /// <summary> /// original comment : not entirely correct implementation as some names /// are correct <br />but it still returns False, but that occurs only /// with names using <br />characters outside the american alphabet /// </summary> function IsValidTagName(const ATagName: WideString): Boolean; /// <summary> /// a too simple check for invalid characters, more or less correct for /// ANSI names. /// </summary> /// <remarks> /// [#0..#$40,#$5B..#$60,#$7B..#$FF]; <br />InvalidOtherChar = /// [#0..#$2C,#$5B..#$60,#$7B..#$B6,#$B8..#$FF]; <br /> /// ValidNameOtherChar:WideString = /// ['a'..'z','A'..'Z','_',':','0'..'9','.','-']; /// </remarks> function IsValidAttributeName(const AAttributeName: WideString): Boolean; procedure Indent; function IsTagStarted: Boolean; function LastTag: String; function MakeValidAttributeValue(const AValue: String): String; procedure AssertLastTagClosed; public constructor Create; destructor Destroy; override; procedure AddRaw(const Data: String); procedure AddNewLine; procedure SetAttribute(const Attribute, Value: String); function ToString: String; procedure StartTag(const Tag: String); procedure StopTag; procedure SavetoFile(Filename : string); end; type TGRAPHMLStreamWriter = class(TXMLStreamWriter) procedure AddHeader; procedure AddFooter; end; implementation { TXMLStreamWriter } function TXMLStreamWriter.IsValidTagName(const ATagName: WideString): Boolean; begin Result := IsValidAttributeName(ATagName); end; procedure TXMLStreamWriter.SavetoFile(Filename: string); begin FStream.SaveToFile(Filename); end; procedure TXMLStreamWriter.AddRaw(const Data: String); var StrLen: integer; begin // Stream.WriteBuffer(Pointer(Str)^, StrLen * SizeOf(Char)); //All Delphi versions compatible StrLen := length(Data); self.FStream.WriteBuffer(Pointer(Data)^, StrLen * SizeOf(Char)) end; constructor TXMLStreamWriter.Create; begin FTagStack := TStringStack.Create; FStream := TStringStream.Create('', TEncoding.UTF8); FIsStartTagClosed := True; end; destructor TXMLStreamWriter.Destroy; begin FTagStack.Free; FStream.Free; inherited; end; function TXMLStreamWriter.ToString: String; begin Result := self.FStream.DataString; end; { TGRAPHMLStreamWriter } procedure TGRAPHMLStreamWriter.AddFooter; begin self.AddRaw('</graphml>'); end; procedure TGRAPHMLStreamWriter.AddHeader; begin self.AddRaw('<?xml version="1.0" encoding="UTF-8"?> '); self.AddRaw('<graphml xmlns="http://graphml.graphdrawing.org/xmlns" '); self.AddRaw('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '); self.AddRaw('xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns '); self.AddRaw('http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> '); AddNewLine; end; |
AW: GraphML, XML Unterschiede im Encoding ?
Klappt dies:
Delphi-Quellcode:
...
XMLMemo.Lines.SavetoFile('e:\test2.graphML', TEncoding.UTF8); ... |
AW: GraphML, XML Unterschiede im Encoding ?
Liste der Anhänge anzeigen (Anzahl: 2)
@ Uwe
nur die test2.graphML kann bereits gelesen werden, Sie wird ja vom Display Memo in meiner demo Anwendung heraus geschrieben . Der Fehler tritt bei test.graphML auf , diese Datei wird von meinem TStringStream heraus geschrieben, und vermutlich wird bei der .AddRow( ...) Funktion immer ein Fehler im encoding gemacht. Mir fehlt aber das Verständnis was nicht klappt . Im Memo in der Anwendung sehen die Daten ja perfekt aus. Die Graph Analysis Software GEPHI ( ![]() |
AW: GraphML, XML Unterschiede im Encoding ?
Zitat:
Delphi-Quellcode:
? Andernfalls endet das in einem wilden Raten.
TGRAPHMLStreamWriter
|
AW: GraphML, XML Unterschiede im Encoding ?
Liste der Anhänge anzeigen (Anzahl: 2)
hier noch die Sourcen einzeln , das ganze Projekt ist lauffähig
|
AW: GraphML, XML Unterschiede im Encoding ?
Zitat:
|
AW: GraphML, XML Unterschiede im Encoding ?
Ich glaube es liegt an AddRaw. Dort wird die Binärdarstellung (UTF-16) des strings in den Stream geschrieben, was das angegebene Encoding außer Kraft setzt. So sollte es gehen:
Delphi-Quellcode:
procedure TXMLStreamWriter.AddRaw(const Data: String);
begin FStream.WriteString(Data); end; |
AW: GraphML, XML Unterschiede im Encoding ?
@Uwe : Danke für die Fehler Suche, Problem ist jetzt gelöst. Ich lade den fertigen Code zum schnellen Schreiben von XML und GraphML File demnächst hier oder auf Github hoch , könnte ja noch mehrere Anwender finden :-)
|
AW: GraphML, XML Unterschiede im Encoding ?
Zitat:
Delphi-Quellcode:
nicht wirklich brauchst oder? Die wird bei mir automatisch erzeugt, wenn ich den Marabu Code verwende. Außerdem, hast du dir den folgenden Codeschnipsel im selben verlinkten
self.AddRaw('<?xml version="1.0" encoding="UTF-8"?> ');
![]()
Delphi-Quellcode:
Hier zeigt der Marabu wie man anstatt von TMemo Feld das Ergebnis direkt in eine Datei umleiten kann. Damit spart man sich auch Probleme beim Konvertieren. Es funktionierte bei mir auf Anhieb.
begin
// ... fn := 'c:\daten\dp\sax-demo.xml'; fs := TFileStream.Create(fn, fmCreate); wrt := CoMXXMLWriter.Create; cnth := wrt as ISAXContentHandler; wrt.output := TStreamAdapter.Create(fs, soReference) as IStream; cnth.startDocument; dc.Serialize(cnth); cnth.endDocument; wrt.flush; fs.Free; // ... end; Edit: Ok, Asche auf mein Haupt :duck: ich habe da wohl ein Blödsinn bzgl. UTF8 Formatierung erzählt. Automatisch wird bei mir UTF16 von MSXML verwendet. Ich bleibe aber dabei, dass man die Codierung lieber dem MSXML überlassen sollte statt selber reinzupfuschen. Mit folgenden Code kann man die Codierung beeinflussen:
Delphi-Quellcode:
begin
// ... fn := 'c:\daten\dp\sax-demo.xml'; fs := TFileStream.Create(fn, fmCreate); wrt := CoMXXMLWriter.Create; cnth := wrt as ISAXContentHandler; wrt.output := TStreamAdapter.Create(fs, soReference) as IStream; wrt.encoding := 'utf-8'; // <-----------------standardmäßig geht er auf UTF-16 cnth.startDocument; dc.Serialize(cnth); cnth.endDocument; wrt.flush; fs.Free; // ... end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:19 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