AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Datensätze aus Tabelle holen und in Datei speichern
Thema durchsuchen
Ansicht
Themen-Optionen

Datensätze aus Tabelle holen und in Datei speichern

Ein Thema von Back2Code · begonnen am 29. Mai 2013 · letzter Beitrag vom 3. Jun 2013
Antwort Antwort
Benutzerbild von Back2Code
Back2Code

Registriert seit: 6. Feb 2012
Ort: Deutschland
272 Beiträge
 
Delphi XE7 Professional
 
#1

Datensätze aus Tabelle holen und in Datei speichern

  Alt 29. Mai 2013, 09:24
Datenbank: MySQL • Version: 50529 • Zugriff über: UniDac
Ich habe folgendes Problem:

Ich habe eine Tabelle mit 5000 Zufällig generierten Demo Datensätzen



Diese möchte ich jetzt Zeile für Zeile in eine Xliff Datei exportieren.

So sollte dann das Endergebnis aussehen. Kleines Beispiel

Code:
<?xml version='1.0' encoding='utf-8'?>
<xliff version="1.1">
  <file original="source\simple.htm" source-language="EN" target-language="DE" datatype="html">
    <header>
      <skl>
        <external-file uid="017dbcf0-c82c-11e2-ba2b-005056c00008" href="skl\simple.htm.skl"/>
      </skl>
    </header>
    <body>
      <trans-unit id="00QlKZsL6GyW6B92Ev81Fb2HP3Z0ma">
        <source xml:lang="EN">2hH3khJvy1gmFNTLSB0Crka0A8TTKReuYxbV2hI9E8AjXwCV3F</source>
        <target xml:lang="DE">3ydQZWavaKvxrlbh1ewXZakLL00LEPG6zVTyty6fiLrPdx9UE4</target>
      <note/></trans-unit>
      <trans-unit id="016ynILnditynwtYwcl6vJPTLCzvo7">
        <source xml:lang="EN">dyC28VRCI9O37PTHENinp4sgMkr5R0HO1Yo53hUQKNr4GoLFG4</source>
        <target xml:lang="DE">sEkgstffmS4k5KB1JZkNSYbUnzzlFBNT30oYmtfId8dnspG3No</target>
      <note>Testnotiz</note></trans-unit>
      <trans-unit id="03YNBAZ1YWvkqaG4PRxKSiWENOCXuB">
        <source xml:lang="EN">BHpY8LDs8oJAr8I1EfZzeJX24GZ3TLIr9GUAYcnSPYHjDfKRqk</source>
        <target xml:lang="DE">7Rd7bW2lg2Uc4uStCoosZuNgOzA9qWN7OsvW2gBcHa3ctnmF3Q</target>
      <note/></trans-unit>
    </body>
  </file>
</xliff>
Als Komponente für das Bearbeiten/Einfügen der Xliff Datei wollte ich mir XMLDocument schnappen. Hatte mir schon vor ein paar Tagen ein Demoprogramm geschrieben wo ich per XMLDocument eine Xliff Datei lade und anschließend auch wieder etwas reinschreibe. Also diese Routinen zumindestens für die Targets habe ich bereits.

Es geht mir jetzt vielmehr darum, dass ich noch keine richtige Idee habe wie die ganzen Daten aus der MySQL Tabelle am besten Szück wie Stück in eine Xliff Datei packe.

Erster Gedanke war von mir eventuell, durch die komplette Tabelle Zeile für Zeile zu gehen, diese dann in ein Array zu speichern und dann per Schleife drüberzugehn und in die Datei zu schreiben.

Würde mich über ein paar andere Vorschläge / Konzepte freuen. Da es im Endeffekt um einen Test von der Geschwindigkeit der XMLDocument Komponenete geht wären mir Konzepte / Ideen die zu einem schnellen Ablauf führen am liebsten.
Miniaturansicht angehängter Grafiken
20130529101222000051.png  
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#2

AW: Datensätze aus Tabelle holen und in Datei speichern

  Alt 29. Mai 2013, 20:24
Wenn ich das recht sehe, benötigst Du für jede Zeile Deiner Tabelle diesen Part:
Code:
      <trans-unit id="016ynILnditynwtYwcl6vJPTLCzvo7">
        <source xml:lang="EN">dyC28VRCI9O37PTHENinp4sgMkr5R0HO1Yo53hUQKNr4GoLFG4</source>
        <target xml:lang="DE">sEkgstffmS4k5KB1JZkNSYbUnzzlFBNT30oYmtfId8dnspG3No</target>
      <note>Testnotiz</note></trans-unit>
Es ist nicht erforderlich die Tabelle erst in ein Array zu schreiben und dann dieses in die Datei zu exportieren.
Die Tabelle ist letztlich auch nichts Anderes, als ein Array, welches Du zeilenweise abarbeiten kannst.

Mal so (ohne zu prüfen) hingedaddelt:
Delphi-Quellcode:
begin
  tabelle.First;
  while not tabelle.EoF do begin
     AddNode(tabelle.FieldByName('ID').AsString,
             tabelle.FieldByName('src').AsString,
             tabelle.FieldByName('dst').AsString)
    tabelle.Next;
  end;
end;
Zitat von Polymorphin:
Also diese Routinen zumindestens für die Targets habe ich bereits.
AddNode wäre hier also diese Routine, die die drei Parameter aus der Datenbank entsprechend verarbeitet und die Targets quasi zeilenweise in die Datei einfügt.
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#3

AW: Datensätze aus Tabelle holen und in Datei speichern

  Alt 29. Mai 2013, 20:39
Genau. Datensatzweise durchlaufen und direkt mit AddNode in die XML Datei schreiben ist perfekt.
Wenn Du die Tabelle dann noch Readonly öffnest (und falls unterstützt mit einem "ForwardOnly" Cursor), dann ist der Export auch fix erledigt.
Abhängig von den verwendeten DB Komponenten musst du darauf achten, dass tatsächlich alle Datensätze beim Öffnen der Tabelle gefetcht werden.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Datensätze aus Tabelle holen und in Datei speichern

  Alt 30. Mai 2013, 01:27
Crosspost: http://stackoverflow.com/questions/1...d-save-to-file
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
Benutzerbild von Back2Code
Back2Code

Registriert seit: 6. Feb 2012
Ort: Deutschland
272 Beiträge
 
Delphi XE7 Professional
 
#5

AW: Datensätze aus Tabelle holen und in Datei speichern

  Alt 3. Jun 2013, 07:39
Da konnte mir leider niemand weiterhelfen. Den oben beschriebenen Ansatz werde ich ausprobieren
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Datensätze aus Tabelle holen und in Datei speichern

  Alt 3. Jun 2013, 08:09
Da konnte mir leider niemand weiterhelfen. Den oben beschriebenen Ansatz werde ich ausprobieren
Wieso konnte dir da nicht geholfen werden?
Es gibt zwar nur einen Kommentar, aber der trifft doch genau ins Schwarze?
Oder willst du direkt Code haben?
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
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Datensätze aus Tabelle holen und in Datei speichern

  Alt 3. Jun 2013, 09:10
Also hierfür bietet sich das Strategy Design Pattern an.

Hier eine beispielhafte Umsetzung

Delphi-Quellcode:
unit Document;

interface

type
  TDocument = class;

  IDocumentExportFileStrategy = interface
    ['{787B60E5-A3CA-485C-A46E-248A43D7175C}']
    procedure ExportDoc( AContext : TDocument; const AFileName : string );
  end;

  TDocument = class
  private
    FExportFileStrategy : IDocumentExportFileStrategy;
  protected
    function GetValue( const Name : string ) : Variant; virtual; abstract;
  public
    procedure First; virtual; abstract;
    procedure Next; virtual; abstract;
    function Eof : Boolean; virtual; abstract;

    property Value[const Name : string] : Variant read GetValue;

    property ExportFileStrategy : IDocumentExportFileStrategy read FExportFileStrategy write FExportFileStrategy;

    procedure ExportTo( const AFileName : string );
  end;

implementation

{ TDocument }

procedure TDocument.ExportTo( const AFileName : string );
begin
  FExportFileStrategy.ExportDoc( Self, AFileName );
end;

end.
Die Export-Strategie für Xliff (Plain-Text)
Delphi-Quellcode:
unit XliffPlainExporter;

interface

uses
  Document,

  SysUtils, Variants,
  Classes;

type
  TXliffPlainExporter = class( TInterfacedObject, IDocumentExportFileStrategy )
  private
    procedure WriteLine( AStream : TStream; ALine : string );
  protected
    procedure WriteHead( AContext : TDocument; AStream : TStream );
    procedure WriteDetails( AContext : TDocument; AStream : TStream );
    procedure WriteFoot( AContext : TDocument; AStream : TStream );
  public
    procedure ExportDoc( AContext : TDocument; const AFileName : string );
  end;

implementation

{ TXmlExporter }

procedure TXliffPlainExporter.ExportDoc( AContext : TDocument; const AFileName : string );
var
  LStream : TStream;
  LFileName : string;
begin
  AContext.First;
  if not AContext.Eof
  then
    begin

      LFileName := AFileName;
      if ExtractFileExt( LFileName ) = ''
      then
        LFileName := ChangeFileExt( LFileName, '.xml' );

      LStream := TFileStream.Create( LFileName, fmCreate );
      try
        WriteHead( AContext, LStream );
        WriteDetails( AContext, LStream );
        WriteFoot( AContext, LStream );
      finally
        LStream.Free;
      end;

    end;
end;

procedure TXliffPlainExporter.WriteHead( AContext : TDocument; AStream : TStream );
begin
  WriteLine( AStream, '<?xml version=''1.0'' encoding=''utf-8''?>' );
  WriteLine( AStream, '<xliff version="1.1">' );
  WriteLine( AStream, ' <file original="source\simple.htm" source-language="EN" target-language="DE" datatype="html">' );
  WriteLine( AStream, ' <header>' );
  WriteLine( AStream, ' <skl>' );
  WriteLine( AStream, ' <external-file uid="017dbcf0-c82c-11e2-ba2b-005056c00008" href="skl\simple.htm.skl"/>' );
  WriteLine( AStream, ' </skl>' );
  WriteLine( AStream, ' </header>' );
  WriteLine( AStream, ' <body>' );
end;

procedure TXliffPlainExporter.WriteDetails( AContext : TDocument; AStream : TStream );
begin
  while not AContext.Eof do
    begin
      WriteLine( AStream, Format( ' <trans-unit id="%s">', [VarToStr( AContext.Value['id'] )] ) );
      WriteLine( AStream, Format( ' <source xml:lang="EN">%s</source>', [VarToStr( AContext.Value['src'] )] ) );
      WriteLine( AStream, Format( ' <target xml:lang="DE">%s</target>', [VarToStr( AContext.Value['dst'] )] ) );
      WriteLine( AStream, ' <note/></trans-unit>' );

      AContext.Next;
    end;
end;

procedure TXliffPlainExporter.WriteFoot( AContext : TDocument; AStream : TStream );
begin
  WriteLine( AStream, ' </body>' );
  WriteLine( AStream, ' </file>' );
  WriteLine( AStream, '</xliff>' );
end;

procedure TXliffPlainExporter.WriteLine( AStream : TStream; ALine : string );
var
  LLine : TStream;
begin
  LLine := TStringStream.Create( ALine + sLineBreak, TEncoding.UTF8 );
  try
    LLine.Position := 0;
    AStream.CopyFrom( LLine, LLine.Size );
  finally
    LLine.Free;
  end;
end;

end.
Ein konkretes Test-Dokument
Delphi-Quellcode:
unit TestDocument;

interface

uses
  Document;

type
  TTestDocument = class( TDocument )
  private
    FIndex : Integer;
  protected
    function GetValue( const Name : string ) : Variant; override;
  public
    function Eof : Boolean; override;
    procedure First; override;
    procedure Next; override;
  end;

implementation

uses
  SysUtils,
  StrUtils;

{ TTestDocument }

function TTestDocument.Eof : Boolean;
begin
  Result := FIndex >= 100;
end;

procedure TTestDocument.First;
begin
  inherited;
  FIndex := 0;
end;

function TTestDocument.GetValue( const Name : string ) : Variant;
begin
  case IndexText( Name, ['id', 'src', 'dst'] ) of
    0 :
      Result := Format( 'id%8.8d', [FIndex + 1] );
    1 :
      Result := Format( 'src%8.8d', [FIndex + 1] );
    2 :
      Result := Format( 'dst%8.8d', [FIndex + 1] );
  end;
end;

procedure TTestDocument.Next;
begin
  inherited;
  Inc( FIndex );
end;

end.
und das Hauptprogramm zum Testen
Delphi-Quellcode:
program DataExportStrategy;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  Document in 'Document.pas',
  TestDocument in 'TestDocument.pas',
  XliffPlainExporter in 'XliffPlainExporter.pas';

procedure Test;
var
  LDoc : TDocument;
begin
  LDoc := TTestDocument.Create;
  try
    LDoc.ExportFileStrategy := TXliffPlainExporter.Create;
    LDoc.ExportTo( 'test' );
  finally
    LDoc.Free;
  end;

  WriteLn( 'Export finished' );
end;

begin
  try

    Test;

  except
    on E : Exception do
      WriteLn( E.ClassName, ': ', E.Message );
  end;

  ReadLn;

end.
Wenn du ein TDataSetDocument benötigst, dann bau es dir so
Delphi-Quellcode:
unit DataSetDocument;

interface

uses
  Document,
  Data.DB;

type
  TDataSetDocument = class( TDocument )
  private
    FDataSet : TDataSet;
  protected
    function GetValue( const Name : string ) : Variant; override;
  public
    constructor Create( ADataSet : TDataSet );

    function Eof : Boolean; override;
    procedure Next; override;
    procedure First; override;
  end;

implementation

{ TDataSetDocument }

constructor TDataSetDocument.Create( ADataSet : TDataSet );
begin
  inherited Create;
  FDataSet := ADataSet;
end;

function TDataSetDocument.Eof : Boolean;
begin
  Result := FDataSet.Eof;
end;

procedure TDataSetDocument.First;
begin
  inherited;
  FDataSet.First;
end;

function TDataSetDocument.GetValue( const Name : string ) : Variant;
begin
  Result := FDataSet.FieldByName( Name ).Value;
end;

procedure TDataSetDocument.Next;
begin
  inherited;
  FDataSet.Next;
end;

end.
und fertig ...

Benötigst du weitere (oder anders funktionierende) Export-Formate (z.B. CSV oder XML mit XMLDoc), dann einfach eine neue Strategie-Klasse implemetieren, dem Document zuweisen und Exportieren lassen.
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
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 10: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