Ich löse sowas in der Regel so: Ich pass den Code natürlich an, ob ich jetzt CSS oder HTML oder sonst was parsen möchte:
Code: Alles auswählen
function LoadConfigFile(const aFileName: String; var aStringList:TStrings; DataItem:TPLDataItem): Boolean;
var
FileStream:TFileStream;
ch:char;
inBlock, NoAddChar, NoAddLine, FirstCharLine:Boolean;
LevelIndex:Integer;
Token, Name, Value:String;
LastDataItem, OldDataItem:TPLDataItem;
begin
LevelIndex:=-1;
result:=false;
NoAddChar:=false;
NoAddLine:=false;
FirstCharLine:=true;
Token:='';
Name:='';
Value:='';
DataItem.Items:=TobjectList.Create;
LastDataItem:=DataItem;
if FileExists(aFileName) then begin
result:=true;
FileStream:=TFileStream.Create(aFileName,fmOpenRead);
while true do begin
FileStream.ReadBuffer(ch,1);
if ch = '#' then begin
NoAddLine:=True;
NoAddChar:=True;
end;
if not NoAddLine then begin
if ch = '}' then begin
inBlock:=False;
Token:='';
if LevelIndex-1 >=0 then begin
LevelIndex:=LevelIndex-1;
if LastDataItem.Parent <> nil then begin
LastDataItem:=LastDataItem.Parent;
end
else begin
LastDataItem:=DataItem;
end;
end
else begin
LastDataItem:=DataItem;
end;
NoAddChar:=true;
end;
if ch = '{' then begin
inc(LevelIndex);
if LastDataItem.FindByName(Trim(Token));
LastDataItem:=LastDataItem.Add;
LastDataItem.Items:=TobjectList.Create;
LastDataItem.Name:=Trim(Token);
inBlock:=True;
Name:=Token;
Token:='';
NoAddChar:=True;
end;
// Test Test Test Test
if (ch = ':') and (Name = '') then begin
Name:=Token;
Token:='';
NoAddChar:=true;
end;
end;
if ch in [#13,#10] then begin
if not NoAddLine then begin
if Token <> '' then value:=token;
if Value <> '' then begin
LastDataItem:=LastDataItem.Add;
LastDataItem.Name:=Trim(Name);
LastDataItem.Value:=Trim(Value);
LastDataItem:=LastDataItem.Parent;
end;
Name:=''; Value:='';
end;
Token:='';
NoAddLine:=False;
NoAddChar:=True;
FirstCharLine:=true;
end;
if (FirstCharLine) and (not NoAddChar) then begin
if ch <> ' ' then begin
FirstCharLine:=false;
end
else begin
NoAddChar:=true;
end;
end;
if not NoAddChar then begin
Token:=Token+ch
end
else
NoAddChar:=false;
if FileStream.Position+1 >=FileStream.Size then break;
end; // while
end;
FileStream.Free;
end; // LoadConfigFile
So sieht eine entsprechende Config Datei aus, inzwischen habe ich es stark erweitert.
Code: Alles auswählen
LCDModul2Button {
Typ: REMOTE
Titel: Stellt 8 Buttons zu verfügung
ID: 271
Controler: ArduinoNano
Enabled: ON
Pfad:Arbeitzimmer/Sofa
ParamaterList {
Button1:%PageNext%
Button2:%PagePrev%
Button3:
Button4:
Button5:
Button6:
Button7:%SendModul,/Modul/pmpdApp/PlayPause%
Button8:%SendModul,/Modul/pacAPP/Serial/35,CMD,OUT,2%
}
Location {
Sensor1:Arbeitzimmer
}
}
TStringlist würde ich nicht nehmen, da sie immer erst die Datei komplett einlist und dann kann mit der Verarbeitung angefangen werden.
Mit TFileStream spart man sich das. Es ist auch nur geringfügig aufwendiger.