AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

GraphML, XML Unterschiede im Encoding ?

Ein Thema von bernhard_LA · begonnen am 28. Apr 2022 · letzter Beitrag vom 28. Apr 2022
Antwort Antwort
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#1

GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 00:01
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 ( https://graphia.app/ ) eingelesen, die Datei test.graphML wird nicht als gültige XML Datei erkannt.

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;
Miniaturansicht angehängter Grafiken
graphia.png  
Angehängte Dateien
Dateityp: zip test.zip (1,6 KB, 2x aufgerufen)
Dateityp: zip DPraxis_demoXML_writer.zip (5,2 KB, 2x aufgerufen)

Geändert von bernhard_LA (28. Apr 2022 um 13:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.452 Beiträge
 
Delphi 12 Athens
 
#2

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 00:21
Klappt dies:

Delphi-Quellcode:
...
XMLMemo.Lines.SavetoFile('e:\test2.graphML', TEncoding.UTF8);
...
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 10:55
@ 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 (https://gephi.org/) verwende ich zur Anzeige der Graphen, screen dump mit dem testgraphen
Miniaturansicht angehängter Grafiken
start_gephi.jpg   stop_gephi.jpg  

Geändert von bernhard_LA (28. Apr 2022 um 13:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.452 Beiträge
 
Delphi 12 Athens
 
#4

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 11:04
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,
Gibt es denn irgendwo die Sourcen zu TGRAPHMLStreamWriter ? Andernfalls endet das in einem wilden Raten.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 12:27
hier noch die Sourcen einzeln , das ganze Projekt ist lauffähig
Angehängte Dateien
Dateityp: pas TGRAPHML_XMLWriter.pas (8,6 KB, 4x aufgerufen)
Dateityp: pas unit_TGraphML_XMLWriter.pas (8,6 KB, 5x aufgerufen)

Geändert von bernhard_LA (28. Apr 2022 um 14:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.452 Beiträge
 
Delphi 12 Athens
 
#6

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 13:08
das ganze Projekt ist lauffähig
Nicht ganz - es fehlt noch diese Unit: C:\repos\let\codes\code_minor_subprojects\OTHERS software and code testing tools\XML_StreamWriter\Unit_XMLStreamWriter.pas
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.452 Beiträge
 
Delphi 12 Athens
 
#7

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 13:13
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;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 18:47
@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
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
344 Beiträge
 
Delphi 2007 Professional
 
#9

AW: GraphML, XML Unterschiede im Encoding ?

  Alt 28. Apr 2022, 19:14
ich schreibe mit diesem Code GraphML, XML Dateien :

Delphi-Quellcode:

{ 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;
Da ich bisher nur mit DOM gearbeitet habe, hat mich der SAX Ansatz auch sehr interessiert, darum habe ich den Code von Marabu auch gleich ausprobiert. Heute am Abend möchte das Einlesen mit SAX ausprobieren. Aber was mir aufgefallen ist, dass du eigentlich die folgende Zeile
self.AddRaw('<?xml version="1.0" encoding="UTF-8"?> '); 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 Marabu Beitrag angeschaut?
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;
  cnth.startDocument;
  dc.Serialize(cnth);
  cnth.endDocument;
  wrt.flush;
  fs.Free;
  // ...
end;
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.

Edit:
Ok, Asche auf mein Haupt 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;

Geändert von jus (29. Apr 2022 um 14:00 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:33 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