Simple HTML Parser
migajek
W jaki sposob "wyciągnąć" z wskazanego taga HTML jego właściwości?
Funkcja zwraca rekord, w ktorym mamy nazwe "zparsowanego" taga oraz tablice z właściwościami (nazwa_wlasciwosci,wartosc).
Kod jest bardzo niedoskonały, ale ma mozliwosc wyciagania wartosci z tagow w formacie
nazwa="wartosc"
nazwa='wartosc'
nazwa=wartosc
Narazie nie bylo to testowane na wielu plikach, no ale zawsze cos :)
Jeśli znajdziesz jakikolwiek błąd, napisz do mnie na migajek(Eustachy)yahoo(Zdzisiek)com
Proszę o ocenę i sugestie :)
A oto kod:
(*|*******************************|*)
(*| Simple HTML Parser v.0.0.1 |*)
(*| Copyright 2005 |*)
(*| by Michał Gajek |*)
(*| All rights reserved |*)
(*| http://www.migajek.com |*)
(*| migajek@yahoo.com |*)
(*
ToDo :
[x] obslugiwac tagi bez wlasnosci (np <b>, <br> itp)
[x] pobierac dokladniej nazwy parametrow
[ ] tagi w formacie nazwa = "wartosc" czasem nawalaja
*)
unit HTMLParser;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs;
type
THTMLParsedValue = record
Name : string;
Value : string;
end;
THTMLParsedValues = record
TagName:string;
Values: array of THTMLParsedValue;
end;
function ParseHTML(s:string;TagName:string):THTMLParsedValues;
implementation
function ParseHTML(s:string;TagName:string):THTMLParsedValues;
const
DivTag : char = '|';
var
res:THTMLParsedValues;
TagBeginPos,TagEndPos:integer;
TagStr,TagContent:string;
i,j:integer;
InValue:bool; //czy jestesmy w wartosci jakiejs?
ts:TStringList;
begin
inValue:=false;
TagBeginPos:=pos(tagName,s);
//if TagName='' then TagBeginPos:=1; //jak pusty to na 1 :D
TagEndPos:= pos('>',copy(s,TagBeginPos,length(s)));
TagStr:=Copy(s,TagBeginPos,TagEndPos); //wyciety tag
if pos(' ',tagstr)<>0 then
res.TagName:=copy(tagstr,pos('<',tagstr)+1,pos(' ',tagstr)-1)//nazwa taga
else
res.TagName:=copy(tagstr,pos('<',tagstr)+1,pos('>',tagstr)-2);//nazwa taga
TagContent:=copy(TagStr,length(res.TagName)+2,length(tagstr)-length(tagname)-2);//zawartosc (czyli bez nazwy i koncowki)
if tagcontent = '' then exit;
{=== usuwanie zbednych spacjii ===}
for i:=length(Tagcontent) downto 1 do
begin
if (TagContent[i]= '"')or(TagContent[i]= #$27) then //jesli znaleziono poczatek lub koniec lanucha
begin
if TagContent[i+1] <>'' then //jesli nie jest to zakonczenie/poczatek
begin
InValue:=not InValue; //zmieniamy wartosc
if InValue then
Insert(DivTag,TagContent,i+1); //wstawiamy tag rozdzielenia
end;
end;
if (TagContent[i] = ' ') and (TagContent[i+1]= ' ') then //jesli swie spacje pod rzad
if not inValue then //jesli w wartosci
Delete(TagContent,i,1); //skasuj
end;
//sshowmessage(tagcontent);
for i:=length(Tagcontent) downto 1 do
begin
if (TagContent[i]='"')or(TagContent[i]=#$27) then
if TagContent[i-1] ='' then
Delete(TagContent,i-1,1)
else
Delete(TagContent,i,1)
end;
//usuwanie spacji z nazwy taga
if res.TagName<>'' then
begin
while res.TagName[1] = ' ' do
Delete(res.TagName,1,1);
while res.TagName[length(res.TagName)] = ' ' do
Delete(res.TagName,length(res.TagName),1);
end;
//usuwanie znakow z poczatku i konca lini
if TagContent<>'' then
begin
while TagContent[1] = ' ' do
Delete(TagContent,1,1);
while TagContent[length(tagcontent)] = ' ' do
Delete(TagContent,length(tagcontent)-1,1);
end;
ts:=TStringList.Create;
ExtractStrings([DivTag],[' '],PChar(tagcontent),ts);
for j:=0 to ts.Count-1 do
begin
if Copy(ts.Strings[j],1,pos('=',ts.Strings[j])-1)<>'' then
begin
SetLength(res.Values,Length(res.Values)+1);
res.Values[high(res.values)].Name:=Copy(ts.Strings[j],1,pos('=',ts.Strings[j])-1);
res.Values[high(res.values)].Value:=Copy(ts.Strings[j],length(res.Values[high(res.values)].Name)+2,length(ts.Strings[j]));
if res.Values[high(res.values)].Name<>'' then
begin
while res.Values[high(res.values)].Name[1] = ' ' do
Delete(res.Values[high(res.values)].Name,1,1);
while res.Values[high(res.values)].Name[length(res.Values[high(res.values)].Name)] = ' ' do
Delete(res.Values[high(res.values)].Name,length(res.Values[high(res.values)].Name)-1,1);
end;
end;
end;
result:=res;
end;
end.
DJ Orange: raczej nie :]
A ten twoj edytor html bedzie Open Source <lol> ?
Wolverine: thx za linka, ale samemu czasem tez warto :) No ale moze sie przydac, jak trzeba bedzie dopracowywac :)
Polecam http://regexpstudio.com/, latwiej sie takie rzeczy robi.
Poprawiłem troche kod, mam nadzieje ze bedzie lepiej dzialac.
O sorry... Parser powstal na potrzeby mojego edytora html i po prostu zostalo tam w uses... :P Wywal to :P
MemoUtils i Decl to jakies dodatkowe komponenty ? :| bo przy kompilacji na d7 ent. wyskakuje ze brak wlasnie tego :|
przydzało by sie tez na formę taką:
nazwa = "wartość"
czyli ze spacjami, w rożnych kombinacjach of course.. no chyba, że już to masz - nie testowałem.
Deti: nie mam chyba :P Jeszcze sie moze pobawie... Jak cos zmienie to napisze :)
Marooned : ta, wiem... po prostu najpierw pisalem arta a potem wklejalem tresc pliku ;)
p.s. serio? :P
Ukryłeś maila przed botami "migajek(Eustachy)yahoo(Zdzisiek)com" a 5 linijek niżej podałeś w normalnej formie :]
p.s. pisze się 'na razie' ;)