Мне надо прочитать настройки из XML - подобного (именно подобного!!!) файла. Например,| Код | <graphics> <width>1024</width> <height>768</height> <antialiasing>true</antialiasing> </graphics> <sound> <volume>100</volume> </sound>
|
Для этих целей я создал модуль, который работает наподобие TIniFile:
| Код | unit ZD_ZMLParser;
interface
uses SysUtils, Classes;
type TZMLParser = class private Data: TStringList; _ZMLFileName: string; function _Read(const ASection, AKey: string): string; procedure _Write(ASection, AKey, AValue: string); public constructor Create(const AZMLFileName: string); function ReadString(const ASection, AKey: string): string; function ReadInteger(const ASection, AKey: string): integer; function ReadBoolean(const ASection, AKey: string): boolean; procedure WriteString(const ASection, AKey: string; AValue: string); procedure WriteInteger(const ASection, AKey: string; AValue: integer); procedure WriteBoolean(const ASection, AKey: string; AValue: boolean); procedure UpdateZMLFile; destructor Destroy; override; end;
implementation
function TwoSideTrim(AString: string): string; begin Result := TrimLeft(TrimRight(AString)); end;
function GetCharCount(AString: string; AChar: char): integer; var _Index: integer; begin _Index := 0; repeat Inc(_Index); until AString[_Index] <> AChar; Result := _Index; end;
function FillStr(AChar: char; ACount: integer): string; var _Index: integer; begin for _Index := 0 to ACount do Result := Result + AChar; end;
constructor TZMLParser.Create(const AZMLFileName: string); begin Data := TStringList.Create; if FileExists(AZMLFileName) then Data.LoadFromFile(AZMLFileName); _ZMLFileName := AZMLFileName; end;
function TZMLParser._Read(const ASection, AKey: string): string; var _Data: string; _Index, _SectionBegin, _SectionEnd: integer; begin _SectionBegin := -1; _SectionEnd := -1; for _Index := 0 to Data.Count - 1 do begin _Data := TwoSideTrim((Data[_Index])); if Pos('<' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then _SectionBegin := _Index; if Pos('</' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then begin _SectionEnd := _Index; Break; end; end; for _Index := _SectionBegin + 1 to _SectionEnd - 1 do begin _Data := TwoSideTrim((Data[_Index])); if Pos('<' + LowerCase(AKey) + '>', LowerCase(_Data)) = 1 then begin Delete(_Data, 1, Length('<' + AKey + '>')); Delete(_Data, Length(_Data) - Length('</' + AKey + '>') + 1, Length('</' + AKey + '>')); Result := _Data; Break; end; end; end;
procedure TZMLParser._Write(ASection, AKey, AValue: string); var _Data: string; _Index, _SectionBegin, _SectionEnd: integer; begin _SectionBegin := -1; _SectionEnd := -1; ASection := LowerCase(ASection); AKey := LowerCase(AKey); if _Read(ASection, AKey) = '' then begin if Data.Count <> 0 then begin for _Index := 0 to Data.Count - 1 do begin _Data := TwoSideTrim(Data[_Index]); if Pos('<' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then _SectionBegin := _Index; if Pos('</' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then begin _SectionEnd := _Index; Break; end; end; if _SectionBegin = -1 then begin Data.Add('<' + ASection + '>'); Data.Add(Format(' <%s>%s</%s>', [AKey, AValue, AKey])); if _SectionEnd = -1 then Data.Add('</' + ASection + '>'); end; end else begin Data.Add('<' + ASection + '>'); Data.Add(Format(' <%s>%s</%s>', [AKey, AValue, AKey])); Data.Add('</' + ASection + '>'); end; end else begin for _Index := 0 to Data.Count - 1 do begin _Data := TwoSideTrim(Data[_Index]); if Pos('<' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then _SectionBegin := _Index; if Pos('</' + LowerCase(ASection) + '>', LowerCase(_Data)) = 1 then begin _SectionEnd := _Index; Break; end; end; for _Index := _SectionBegin + 1 to _SectionEnd - 1 do begin _Data := TwoSideTrim((Data[_Index])); if Pos('<' + LowerCase(AKey) + '>', LowerCase(_Data)) = 1 then Data[_Index] := Format('%s<%s>%s</%s>', [FillStr(' ', GetCharCount(_Data, ' ')), AKey, AValue, AKey]); end; end; end;
function TZMLParser.ReadString(const ASection, AKey: string): string; begin Result := _Read(ASection, AKey); end;
function TZMLParser.ReadInteger(const ASection, AKey: string): integer; var _Result: integer; begin if TryStrToInt(_Read(ASection, AKey), _Result) then Result := _Result else Result := 0; end;
function TZMLParser.ReadBoolean(const ASection, AKey: string): boolean; var _Result: string; begin _Result := Trim(LowerCase(_Read(ASection, AKey))); if (_Result = 'true') or (_Result = 'yes') or (_Result = '1') then Result := true else Result := false; end;
procedure TZMLParser.WriteString(const ASection, AKey: string; AValue: string); begin _Write(ASection, AKey, AValue); end;
procedure TZMLParser.WriteInteger(const ASection, AKey: string; AValue: integer); begin _Write(ASection, AKey, IntToStr(AValue)); end;
procedure TZMLParser.WriteBoolean(const ASection, AKey: string; AValue: boolean); begin case AValue of true: _Write(ASection, AKey, 'true'); false: _Write(ASection, AKey, 'false'); end; end;
procedure TZMLParser.UpdateZMLFile; begin Data.SaveToFile(_ZMLFileName); end;
destructor TZMLParser.Destroy; begin inherited Destroy; Data.Free; end;
end.
|
Что-то мне не нравится, как он работает, а на отладку просто нет времени! Помогите, ибо на вас последняя надежда! |