|
|
HTML kódok eltávolítása tetszőleges szövegből
|
|
Példaprogram letöltése
11907 bájt
|
Ha egy HTML formátumú dokumentumból nekünk csak a szövegre van szükségünk, akkor megtehetjük azt, hogy megnyitjuk egy böngészővel, majd elmentjük TXT formátumban. Ez nem rossz megoldás, de mi a helyzet, ha ugyanezt programból szeretnénk megtenni. A megoldás egy komponens, ami a megadott HTML kódból visszaadja a szöveget, méghozzá úgy, hogy egy jól olvasható, könnyen felhasználható szöveget kapunk.
A mellékelt példaprogram megnyitása előtt a HtmlToText.pas-ban lévő komponenst telepítenie kell a Delphi alá.
Amikor egy HTML kódot konvertálunk egyszerű szöveg fájllá, akkor az eredmény nem mindig kielégítő. A fájl elején, közben és végén sokszor üres sorok találhatók, valamint a sorok előtt felesleges szóközök lehetnek. Az új komponensnek tehát mindezeket a hibákat ki kell küszöbölnie. A komponens még így sem ad minden esetben megfelelő eredményt, mivel a táblázatokat nem kezeli. A táblázat celláiban lévő adatok egymás után, folyamatos szövegként jelennek meg.
A komponensnek csupán három új property-je van. A HTML property-ben kell megadni a konvertálandó HTML kódot, a TrimLines property igaz érték esetén a felesleges sorok, és szóközök törlését engedélyezi. Az eredményt a Text property-ben kapjuk meg.
A konvertálás az Execute eljárás meghívásával történik.
Első lépésben töröljük a Text property-t, amiben az eredményt fogjuk megkapni. A htm változóban tároljuk el a HTML kódot, de egy kicsit átalakítjuk a konvertálás előtt. Rögtön az első értékadás úgy történik, hogy töröljük a sortöréseket. Ezután az összes 160-as kódú szóköz karaktert helyettesítjük a #32 kódú (normál) szóköz karakterrel. Ezután a dupla szóközöket szimpla szóközökkel helyettesítjük, így töröljük a felesleges szóközöket. Mivel előzőleg töröltük a sortöréseket, ezért most már a tényleges sortörések helyére ("<BR>") beilleszthetjük a megfelelő kódot.
FText.Clear;
htm:=StringReplace(FHTML.Text, #13#10, #32, [rfReplaceAll, rfIgnoreCase]);
htm:=StringReplace(htm, #160, #32, [rfReplaceAll]);
htm:=StringReplace(htm, #32#32, #32, [rfReplaceAll]);
htm:=StringReplace(htm, '<BR>', #13#10, [rfReplaceAll, rfIgnoreCase]);
A HTML dokumentumban a tényleges tartalom a "<BODY>" kód után kezdődik, ezért töröljük a kód elejét, hogy a konvertálás csak ettől a résztől kezdődjön.
ok:=false;
while (length(htm)>0) and not ok do begin
if UpperCase(Copy(htm, 1, 5))<>'<BODY' then
Delete(htm, 1, 1)
else
ok:=true;
end;
Egy ciklust indítunk, amiben karakterenként beolvassuk a már módosított HTML kódot. A ciklus egészen addig tart, amíg végig nem értünk a kódon (htm változó). Az i változó a konvertálandó karakter sorszáma.
i:=1; Tag:=false; Txt:=false; tx:='';
while i<=Length(htm) do begin
Ellenőrizzük, hogy a beolvasott karakter nem "<" karakter-e. Ha az, akkor itt egy HTML kód kezdődik, ami egészen a ">" karakterig tart és a Tag változó értékét igazra, a Txt változó értékét pedig hamisra állítjuk. A Tag változó értéke akkor igaz, ha egy HTML kódban vagyunk, tehát az itt található szöveget nem kell konvertálni. A Txt változó jelentőségéről később lesz szó.
case htm[i] of
'<': begin
Tag:=true; txt:=false;
end;
Ha ">" karaktert találtunk, akkor vége van a HTML kódnak, tehát a Tag változó értékét hamisra állítjuk. A tx változóban tároljuk a már konvertált szöveget. Ellenőrizzük, hogy van-e már konvertált szöveg, és ha van, akkor megnézzük, hogy az utolsó karakter szóköz, vagy sortörés-e. Ha egyik feltétel sem igaz, akkor egy szóköz karaktert hozzáadunk a szöveghez. Erre azért van szükség, mert néhány esetben a szavak között nem lett volna szóköz. Például ennél a HTML kódnál: "…>egy<p> kettő</p>" a következő eredményt kaptuk volna: "egykettő".
'>':
begin
if (length(tx)>1) then
if not (tx[length(tx)] in [#32, #10]) then tx:=tx+#32;
Tag:=false; Txt:=false;
end;
Ha nem "<" és ">" karaktereket találtunk, akkor megnézzük, hogy a beolvasott karaktert hozzá kell-e adni a konvertált szöveghez. Ha az utolsó konvertált karakter szóköz, akkor nem engedélyezzük az új karakter hozzáadását a konvertált szöveghez. A következő sorban ("Txt:=…") egy összetett feltétel van, aminek jelentése a következő: ha a Txt igaz, és nem HTML kódon belül vagyunk, és a konvertálandó karakter nem szóköz, akkor hozzáadhatjuk a karaktert a konvertált szöveghez (Txt=igaz).
else
if (i>1 ) and (htm[i-1]=#32) then Txt:=false;
Txt:=Txt or ((not Tag) and (htm[i]<>#32));
if not Tag and Txt then begin
tx:=tx+htm[i];
end;
end;
inc(i);
end;
Ha végigértünk a HTML kódon, és a szöveges részt kiolvastuk, akkor még koránt sem végeztünk a konvertálással, hiszen a HTML szöveg speciális azonosítókat is tartalmazhat. Ezeket az ISOCS konstans tömbben tároltuk, aminek első eleme a karakter kódja, a második a HTML kód, ami a karaktert helyettesíti. Itt egyszerű dolgunk van, mivel csak végig kell menni ezen a tömbön, és a StringReplace függvénnyel az összes kódot kicserélni a kódnak megfelelő karakterrel.
for i:=1 to NISOCS do begin
tx:=StringReplace(tx, ISOCS[i, 2], ISOCS[i,1], [rfReplaceAll, rfIgnoreCase]);
end;
Mivel a HTML kód tartalmazhat " " kódokat, ami a 160-as kódú szóköznek felel meg (és nem "á" betű!), ezért ezeket újra ki kell cserélnünk egyszerű 32-es kódú szóközökre.
tx:=StringReplace(tx, #160, #32, [rfReplaceAll]);
A Text property-nek most már átadhatjuk a konvertált szöveget.
Amennyiben a TrimLines property értéke igaz, akkor még nem végeztünk. A konvertált szövegből törölnünk kell a felesleges üres sorokat és szóközöket, amit szintén egy ciklusban teszünk meg.
|
Könyv
Ez a cikk megtalálható ebben a könyvben:
Delphi Software Offline 2001 évkönyv 386. oldal
Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!
|