2016-11-15 6 views
-1

Nachdem ich Delphi extract string between to 2 tags angesehen und den dort angegebenen Code von Andreas Rejbrand ausprobiert hatte, erkannte ich, dass ich eine Version brauchte, die nach einem Tag nicht aufhört - mein Ziel ist es, alle zu schreiben Werte, die zwischen zwei Zeichenfolgen in mehreren XML-Dateien in einer Protokolldatei auftreten.Alle Zeichenfolgen zwischen zwei anderen Zeichenketten in Logfile schreiben

<screen> xyz </screen> blah blah <screen> abc </screen> 

-> gibt ein Logfile mit
xyz
abc
... und so weiter.

Was ich versuchte war, einen Teil des von der Funktion gelesenen Textes zu löschen, so dass, wenn die Funktion wiederholt wurde, es zur nächsten Instanz der gewünschten Zeichenfolge gehen würde und diese auch in die Protokolldatei schreiben würde, bis es keine gab Übereinstimmungen links - die boolesche Funktion wäre wahr und die Funktion könnte anhalten - unterhalb der leicht modifizierten Funktion, basierend auf der Version in der Verbindung.

function ExtractText(const Tag, Text: string): string; 
var 
    StartPos1, StartPos2, EndPos: integer; 
    i: Integer; 
    mytext : string; 
    bFinished : bool; 

begin 
    bFinished := false; 
    mytext := text; 
    result := ''; 
    while not bFinished do 
    begin 
    StartPos1 := Pos('<' + Tag, mytext); 
    if StartPos1 = 0 then bFinished := true; 
    EndPos := Pos('</' + Tag + '>', mytext); 
    StartPos2 := 0; 
    for i := StartPos1 + length(Tag) + 1 to EndPos do 
     if mytext[i] = '>' then 
     begin 
     StartPos2 := i + 1; 
     break; 
     end; 

    if (StartPos2 > 0) and (EndPos > StartPos2) then 
    begin 
     result := result + Copy(mytext, StartPos2, EndPos - StartPos2); 
     delete (mytext, StartPos1, 1); 
    end 

Also ich das Formular erstellen und eine Protokolldatei zuweisen.

procedure TTagtextextract0r.FormCreate(Sender: TObject); 
begin 
    Edit2.Text:=(TDirectory.GetCurrentDirectory); 
    AssignFile(LogFile, 'Wordlist.txt'); 
    ReWrite(LogFile); 
    CloseFile(Logfile); 
end; 

Um dann die fraglichen Dateien zu bekommen, klicke ich auf eine Schaltfläche, die sie dann liest.

procedure TTagtextextract0r.Button3Click(Sender: TObject); 
begin 
    try 
    sD := TDirectory.GetCurrentDirectory; 
    Files:= TDirectory.GetFiles(sD, '*.xml'); 
    except 
    exit 
    end; 

    j:=Length(Files); 
    for k := 0 to j-1 do 
    begin 
    Listbox2.Items.Add(Files[k]); 
    sA:= TFile.ReadAllText(Files[k]); 
    iL:= Length(sA); 

    AssignFile(LogFile, 'Wordlist.txt'); 
    Append(LogFile); 
    WriteLn(LogFile, (ExtractText('screen', sA))); 
    CloseFile (LogFile); 
    end; 
end; 

end. 

Mein Problem ist, dass es ohne die boolean-Schleife in der Funktion, nur die Anwendung die eine Zeile pro Datei schreibt und stoppt dann aber mit dem boolean Code der Anwendung in einer Endlosschleife hängen bleibt - aber ich kann nicht Sehen Sie, wo die Schleife nicht endet. Ist es möglich, dass der Befehl "WriteLn" das Ergebnis der Funktion nicht ausgeben kann? Wenn es nicht möglich ist, weiß ich nicht, wie man für jeden Lauf der Funktion eine neue Zeile bekommt - was mache ich hier falsch?

+1

Lernen Sie, 1) Ihren Code richtig einzurücken, damit Sie sehen können, wo Blöcke beginnen und stoppen, und 2) lernen, den Debugger zu benutzen, um den Code zu durchlaufen, um zu sehen, was passiert. Setzen Sie in diesem Fall einen Haltepunkt bei 'ListBox2.Items.Add (Files [k]);' und durchlaufen Sie den Code mit F8, um jede Zeile auszuführen. (Und ein Hinweis: Verschieben Sie 'AssignFile' vor den Loop-Start und' CloseFile' nach dem Loop-Ende. Es hat keinen Sinn, es in jeder Iteration der Schleife wiederholt zu öffnen und zu schließen.) –

+0

Beachten Sie, dass Sie ' PosEx' Funktion, um die Suche von der letzten Position fortzusetzen, so dass die Verwendung von 'delete' vermieden wird. – MBo

+2

Verwenden Sie einen XML-Parser –

Antwort

1

Zuerst müssen Sie auf Debuggen

Blick auf this post für eine Einweisung in den Griff zu bekommen, wie ein Programm zu pausieren und debuggen verwildert.

Lesen Sie auch Setting and modifying breakpoints, um zu erfahren, wie Sie Breakpoints verwenden können. Wenn Sie Ihren Code durchgegangen wären, hätten Sie bald gesehen, wo Sie falsch liegen.

Dann, um Ihr Problem:

In älteren Delphi-Versionen (bis zu Delphi XE2) konnte man die PosEx() Funktion (wie in den Kommentaren vorgeschlagen) verwenden, die den Code in ExtractText() Funktion erheblich vereinfachen würde. Von Delphi XE3 die System.Pos() Funktion mit der gleichen Funktionalität wurde als PosEx() erweitert, dass ein dritten Parameter Offset: integer

Da sind Sie an Delphi 10 Seattle ist, können Sie entweder austauschbar System.StrUtils.PosEx() oder System.Pos() verwenden.

System.StrUtils.POSEX

POSEX() gibt den Index des SubStr in S, beginnend die Suche bei

Offset
function PosEx(const SubStr, S: string; Offset: Integer = 1): Integer; inline; overload; 

Die Implementierung von ExtractText() könnte wie folgt aussehen (mit PosEx()):

function ExtractText(const tag, text: string): string; 
var 
    startPos, endPos: integer; 
begin 
    result := ''; 
    startPos := 1; 

    repeat 
    startPos := PosEx('<'+tag, text, startpos); 
    if startPos = 0 then exit; 
    startPos := PosEx('>', text, startPos)+1; 
    if startPos = 1 then exit; 

    endPos := PosEx('</'+tag+'>', text, startPos); 
    if endPos = 0 then exit; 

    result := result + Copy(text, startPos, endPos - startPos) + sLineBreak; 
    until false; 
end; 

Ich fügte sLineBreak (in Einheit System.Types) nach jedem gefundenen Text hinzu, sonst sollte es funktionieren, wie Sie es beabsichtigten (glaube ich).

+0

In neueren Delphi-Versionen (Unicode) entspricht [System.Pos()] (http://docwiki.embarcadero.com/Libraries/en/System.Pos) "System.StrUtils.PosEx()". –

+1

@LURD heilig ...! So scheint es. Danke, das wusste ich nicht. Ich muss meinen Beitrag neu formulieren. –

+0

@LURD Ich habe eine Lücke in meinen Installationen. D2010 Pos() erkennt den dritten Parameter nicht. DXE4 tut es. Haben Sie XE, XE2 oder XE3 installiert, um zu überprüfen, wann die Änderung stattgefunden hat? –

Verwandte Themen