Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Eingelesene Zeile wird vorzeitig abgetrennt (https://www.delphipraxis.net/180382-eingelesene-zeile-wird-vorzeitig-abgetrennt.html)

Ajintaro 16. Mai 2014 12:31

Eingelesene Zeile wird vorzeitig abgetrennt
 
Hallo DP !

Ich habe diesmal meine Problemstellung weitestgehend selbst lösen können, allerdings gibt es eine Kleinigkeit, die ich mir nicht erklären kann. Ich untersuche folgende HTML-Reihen:

Code:
<tr class="odd">
<td><img title="IR" align="absmiddle" style="margin-right: 3px;" src="img/IR.png"><a title="yx" class="linkClass" onclick="displayLink('display?TRDB=NO&amp;RNID=08399806&amp;noBack=false'); return false" href="javascript:void(0)">08399806</a></td><td>yout title goes here</td><td>New</td><td>Lucky Luke - Online Support</td><td></td><td>Horses are unlucky</td><td>Maria Herbst</td><td>Tomatoes</td><td>16MAY14 07:41</td><td>16MAY14 07:41</td><td>Medium</td><td>
                            No
                   </td><td> </td><td>6653</td><td> </td><td></td>
</tr>
Insgesamt sind es über 300 solcher Reihen mit identischem Aufbau. Ich möchte jede Tablerow beginnend ab dem Suchwort: RNID= bis zum Reihenende </tr> untersuchen, ob darin bestimmte Zahlenreihen vorkommen. Im obigen Beispiel ist die 6653 versteckt.

Meine Lösung funktioniert im Prinzip recht gut und basiert auf einer Funktion und einer Prozedur:

Delphi-Quellcode:
//Diese Funktion gibt mir einen String zwischen einem Text zurück: aus RNID=1234& wird 1234
function getElementValue(const source, startStr, endStr: String; offset:integer):string;
var
  startIndex, endIndex: integer;
begin
  startIndex := PosEx(startStr, source, offset);
  offset := startIndex + 1;

  if (startIndex > 0) then
  begin
    startIndex := startIndex + Length(startStr);
    endIndex := PosEx(endStr, source, startIndex) + Length(endStr);
    Result := MidStr(source, startIndex, endIndex - startIndex-1);
  end
  else
    Result := '';
end;

//Die Prozedur soll das matching der IDs durchführen
procedure TFmain.Button9Click(Sender: TObject);
var
  i,y, p, startpos: Integer;
  s, rnid: string;
begin
  ListBox1.Clear;//Ergebnis Listbox leeren
  for i := 0 to RichEdit1.Lines.Count - 1 do //im Richedit befindet sich der gesamte HTML-Code mit den 300 Tablerows
  begin
    if Pos('RNID=', RichEdit1.Lines.Strings[i]) > 0 then
    begin
      s := '';
      {Die aktuelle Zeile wird nach der Zeichenfolge "RNID=" durchsucht
      und bei Erfolg ab der gefundenen Position ausgelesen, bis das schließende
       Tag </tr> auftritt...}

      for p := Pos('RNID=', RichEdit1.Lines.Strings[i]) to
        Length(RichEdit1.Lines.Strings[i]) do
        if RichEdit1.Lines.Strings[i][p] <> '</tr>' then
          s := s + RichEdit1.Lines.Strings[i][p]
      else
        break;
       
      //Die Zeile wurde identifiziert, nun prüfen ob die SUCH-ID darin vorkommt
       rnid := getElementValue(s,'RNID=','&',1); //RNID aus der Zeile herauslösen

       for y := 0 to listbox_jira.Count-1 do //alle ID Einträge aus der Listbox nacheinander abarbeiten
         begin
           startpos := Pos (listbox_jira.Items[y], s);
           if (startpos > 0) then
             begin
               //Match in die Liste eintragen
               Listbox1.Items.Add('JIRA: '+listbox_jira.Items[y]+' entspricht IR: '+rnid);
             end
             else
             begin
               //nix eintragen
             end;
         end;
    end;
  end;
  // Die Zahl der gefundenen EInträge in Label1 anzeigen...
  if ListBox1.Items.Count > 0 then
    label1.Caption := IntToStr(ListBox1.Items.Count) +
      ' Einträge verglichen'
  else
    label1.Caption := 'Keine IRs gefunden.';
end;
Das Ergebnis ist eigentlich gut: ich erhalte alle 300 IDs und ich vergleiche jede davon mit dem Listbox-Inhalt. Leider wird mein gesuchter Text "abgeschnitten".
In obiger Prozedur sollte der String s aus folgender Zeile bestehen:

Code:
RNID=08399806&amp;noBack=false'); return false" href="javascript:void(0)">08399806</a></td><td>yout title goes here</td><td>New</td><td>Lucky Luke - Online Support</td><td></td><td>Horses are unlucky</td><td>Maria Herbst</td><td>Tomatoes</td><td>16MAY14 07:41</td><td>16MAY14 07:41</td><td>Medium</td><td>
                            No
                   </td><td> </td><td>6653</td><td> </td><td></td>
</tr>
Tatsächlich kommt aber nur folgendes an:

Code:
RNID=08399806&amp;noBack=false'); return false" href="javascript:void(0)">08399806</a></td><td>yout title goes here</td><td>New</td><td>Lucky Luke - Online Support</td><td></td><td>Horses are unlucky</td><td>Maria Herbst</td><td>Tomatoes</td><td>16MAY14 07:41</td><td>16MAY14 07:41</td><td>Medium</td><td>
Gerade der wichtige Teil der versteckten ID wird abgeschnitten und kann somit nicht untersucht werden.

Woran kann den das liegen ? An einem Linefeed ?

himitsu 16. Mai 2014 12:42

AW: Eingelesene Zeile wird vorzeitig abgetrennt
 
Mal so als doofe Frage dahin gestellt:

Das ist doch eine HTML?
Warum liest du die dann nicht nichs als HTML ein und läßt ein HTML-DOM die Arbeit machen?

(falls es valides XHTML ist, dann kann man das natürlich auch als XML einlesen)

Zitat:

An einem Linefeed ?
Keine Ahnung?
Schau doch mal in deinen String/Text, ob sich dort zufällig ein Zeilenumbruch im HTML befindet.

Nja, wobei Lines natürlich bei jedem Zeilenumbruch eine neue Zeile auf macht.

Klaus01 16. Mai 2014 12:44

AW: Eingelesene Zeile wird vorzeitig abgetrennt
 
Hallo,

Du könntest versuchen die Zeilenumbruchzeichen durch Leerzeichen zu ersetzen
und dann die Zeichenkette durchsuchen und ausschneiden.
Delphi-Quellcode:
s:=stringReplace(s,sLineBreak,' ',[rfReplaceAll]);
Grüße
Klaus

Ajintaro 16. Mai 2014 12:55

AW: Eingelesene Zeile wird vorzeitig abgetrennt
 
Zitat:

Zitat von himitsu (Beitrag 1259048)
Mal so als doofe Frage dahin gestellt:

Das ist doch eine HTML?
Warum liest du die dann nicht nichs als HTML ein und läßt ein HTML-DOM die Arbeit machen?

Es ist HTML, aber ich habe keine Erfahrung im Umgang mit HTML-DOM und wie es mir helfen könnte.

himitsu 16. Mai 2014 13:01

AW: Eingelesene Zeile wird vorzeitig abgetrennt
 
Das ist wie ein XML-DOM ala MSDN-Library durchsuchenIXMLDocument, bzw. Delphi-Referenz durchsuchenTXMLDocument.

Das sind Klassen/Komponenten, welche den Text parsen, ihn in eine Klassenstruktur zerlegen und einem dann einen einfachen Zugriff auf die Dateninhalte bieten. Und dazu oftmals noch mit Funktionen zum Suchen.
Also wie JavaScript (oder bei den Browserkomponenten), wo man direkt auf die Elemente der HTML-Datei zugreifen kann.

Das DOM weiß wie die Datenstruktur aufgebaut ist und zerlegt Diese dann natürlich "richtig".

Ajintaro 16. Mai 2014 13:37

AW: Eingelesene Zeile wird vorzeitig abgetrennt
 
Ich habe gerade festgestellt, dass meine Prozedur wirklich die Zeilenumbrüche überspringt ! Mein Abbruchkriterium (lies die Zeile ein bis du </tr> findest) wird niemals erfüllt, da vorher ein Zeilenumbruch erfolgt. Ergo liest die Prozedur auch nur bis zum Zeilenumbruch ein und übergeht den Rest bis zum erneuten Auftreten von RNID= usw.

Ich versuche das nun umzubasteln. Folgendes müsste theoretisch funktionieren:

1. RichEdit Zeilenweise untersuchen auf RNID=
2. Nach gefundener RNID Zeilen weiter absuchen nach bis zum Auffinden von </tr>

Damit habe ich eine Tabellenzeile (aber mehrere RichEdit-Zeilen) abgesucht.

Ajintaro 16. Mai 2014 14:29

AW: Eingelesene Zeile wird vorzeitig abgetrennt
 
Ich habs gelöst:

Delphi-Quellcode:
procedure TFmain.Button10Click(Sender: TObject);
var i,y,p, startpos:integer;
    s,zeile, rnid:string;
begin
 ListBox1.Clear;
 for i := 0 to RichEdit1.Lines.Count - 1 do
  begin
    //RichEdit Zeilenweise absuchen
    if Pos('RNID=', RichEdit1.Lines.Strings[i]) > 0 then
    begin
      //Zeile mit RNID gefunden
      rnid := getElementValue(RichEdit1.Lines.Strings[i],'RNID=','&',1); //RNID herauslösen
    end
    else
    begin
       if rnid <> '' then
       begin
         //nur bei gefundener ID nach J-Ticket suchen
         for y := 0 to listbox_jira.Count-1 do
         begin
           //die ganze box durchgehen...
           startpos := Pos (listbox_jira.Items[y], RichEdit1.Lines.Strings[i]);
           if (startpos > 0) then
             begin
               Listbox1.Items.Add('JIRA: '+listbox_jira.Items[y]+' entspricht IR: '+rnid);
             end;
         end;
       end;
    end;
  end;
  //Ergebnis
  if ListBox1.Items.Count > 0 then
    label1.Caption := IntToStr(ListBox1.Items.Count) +
      ' IRs gefunden.'
  else
    label1.Caption := 'Keine IRs gefunden.';
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf