Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#18

AW: Gedcom-Datei parsen

  Alt 11. Dez 2014, 23:35
Also das hier lädt mir eine komplette StressTest-Demo-Datei ein
Delphi-Quellcode:
procedure TGedFile.LoadFromFile( const Filename: string );
var
  LValue: TDataRecord;
  LCurrent: TNode;
  LCurrentIdx: Integer;
  LLines: TStringList;
  LLine: string;
begin
  LCurrent := Self;
  LCurrentIdx := 0;

  LLines := TStringList.Create;
  try

    LLines.LoadFromFile( Filename );

    for LLine in LLines do
      begin

        LValue := ParseLine( LLine );

        while LCurrentIdx <> LValue.Level do
          begin
            if LCurrentIdx < LValue.Level
            then
              begin
                LCurrent := LCurrent.LastChild;
                Inc( LCurrentIdx );
              end
            else
              begin
                LCurrent := LCurrent.Parent;
                Dec( LCurrentIdx );
              end;
          end;

        if LValue.DataIsReference
        then
          LCurrent := TRefNode.Create( LCurrent, TNodeType.Create( LValue.NodeTypeStr ), LValue.Data, FReferenceDict )
        else
          LCurrent := TDataNode.Create( LCurrent, TNodeType.Create( LValue.NodeTypeStr ), LValue.Data );

        Inc( LCurrentIdx );

        if not LValue.Reference.IsEmpty
        then
          FReferenceDict.Add( LValue.Reference, LCurrent );
      end;

  finally
    LLines.Free;
  end;

end;

function TGedFile.ParseLine( const ALine: string ): TDataRecord;
var
  LValues: TArray<string>;
  LPrefix: string;
begin
  LValues := ALine.Split( [' '], 3 );
  Result.Level := LValues[0].ToInteger;

  // Reference gefunden?
  if LValues[1].StartsWith( '@' )
  then
    begin
      Result.Reference := LValues[1];
      Result.NodeTypeStr := LValues[2];
    end
  else
    begin
      Result.Reference := '';
      Result.NodeTypeStr := LValues[1];
      SetLength( LValues, 2 );
    end;

  LPrefix := string.Join( ' ', LValues );

  Result.Data := ALine.Substring( LPrefix.Length + 1 );
  Result.DataIsReference := Result.Data.StartsWith( '@' );
end;
Damit habe ich die im Speicher und kann auf jeden Knoten ganz gemütlich zugreifen um die Daten nun auszulesen und sonstwie zu verarbeiten. Die erzeugten Nodes parsen hier gar nichts ... wozu auch
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat