unit XMLFiles; interface uses SysUtils, ComObj, msxml, Classes; type { TXMLFile } TXMLFile = class(TObject) private FXMLPage: IXMLDOMDocument; FLoaded: WordBool; FFileName: WideString; public constructor Create; overload; constructor Create(const FileName: WideString); overload; destructor Destroy; override; function Load(const FileName: WideString): Boolean; function LoadXML(const XMLData: WideString): Boolean; procedure ReadVaules(const Section: WideString; Values: TStrings); virtual; function ReadString(const Section: WideString; Default: Widestring): WideString; virtual; function ReadStringValue(const Section, Attribute: WideString; Default: Widestring): WideString; virtual; function ReadBoolValue(const Section, Attribute: WideString; Default: Boolean): Boolean; virtual; function ReadIntegerValue(const Section, Attribute: WideString; Default: Integer): Integer; virtual; function ReadInteger(const Section: WideString; Default: Integer): Integer; virtual; function ReadBool(const Section: WideString; Default: Boolean): Boolean; virtual; function ReadFloat(const Section: WideString; Default: Double): Double; virtual; function ReadDate(const Section: WideString; Default: TDateTime): TDateTime; virtual; function ReadDateTime(const Section: WideString; Default: TDateTime): TDateTime; virtual; function ReadTime(const Section: WideString; Default: TDateTime): TDateTime; virtual; procedure WriteInteger(const Section: WideString; const Value: Integer); virtual; procedure WriteString(const Section: WideString; const Value: Widestring); virtual; function WriteStringValue(const Section, Attribute: WideString; const Value: Widestring): WideString; virtual; procedure WriteIntegerValue(const Section, Attribute: WideString; const Value: Integer); virtual; procedure WriteBoolValue(const Section, Attribute: WideString; const Value: Boolean); virtual; procedure WriteBool(const Section: WideString; const Value: Boolean); virtual; procedure WriteFloat(const Section: WideString; const Value: Double); virtual; procedure WriteDate(const Section: WideString; const Value: TDateTime); virtual; procedure WriteDateTime(const Section: WideString; const Value: TDateTime); virtual; procedure WriteTime(const Section: WideString; const Value: TDateTime); virtual; function SectionExists(const Section: WideString): Boolean; procedure UpdateFile; virtual; procedure SaveToFile(const FileName: string); virtual; function ValueExists(const Section: WideString): Boolean; property Loaded: WordBool read FLoaded; property XMLPage: IXMLDOMDocument read FXMLPage; end; implementation { TXMLFile } constructor TXMLFile.Create(const FileName: WideString); begin inherited Create; FXMLPage := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument; FFileName := FileName; FLoaded := FXMLPage.load(FileName); end; constructor TXMLFile.Create; begin inherited Create; FXMLPage := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument; end; destructor TXMLFile.Destroy; begin FXMLPage := nil; inherited Destroy; end; function TXMLFile.Load(const FileName: WideString): Boolean; begin FFileName := FileName; FLoaded := FXMLPage.load(FileName); Result := FLoaded; end; function TXMLFile.LoadXML(const XMLData: WideString): Boolean; begin FLoaded := FXMLPage.loadXML(XMLData); Result := FLoaded; end; function TXMLFile.ReadBool(const Section: WideString; Default: Boolean): Boolean; begin Result := ReadInteger(Section, Ord(Default)) <> 0; end; function TXMLFile.ReadBoolValue(const Section, Attribute: WideString; Default: Boolean): Boolean; begin Result := ReadIntegerValue(Section, Attribute, Ord(Default)) <> 0; end; function TXMLFile.ReadDate(const Section: WideString; Default: TDateTime): TDateTime; var DateStr: string; SaveThousandSeparator, SaveDecimalSeparator: Char; begin DateStr := ReadString(Section, ''); Result := Default; if DateStr <> '' then try SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; Result := StrToDate(DateStr); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; except on EConvertError do // Ignore EConvertError exceptions else raise; end; end; function TXMLFile.ReadDateTime(const Section: WideString; Default: TDateTime): TDateTime; var DateStr: string; SaveThousandSeparator, SaveDecimalSeparator: Char; begin DateStr := ReadString(Section, ''); Result := Default; if DateStr <> '' then try SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; Result := StrToDateTime(DateStr); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; except on EConvertError do // Ignore EConvertError exceptions else raise; end; end; function TXMLFile.ReadFloat(const Section: WideString; Default: Double): Double; var FloatStr: WideString; SaveThousandSeparator, SaveDecimalSeparator: Char; begin FloatStr := ReadString(Section, ''); Result := Default; if FloatStr <> '' then try SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; Result := StrToFloat(FloatStr); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; except on EConvertError do // Ignore EConvertError exceptions else raise; end; end; function TXMLFile.ReadInteger(const Section: WideString; Default: Integer): Integer; var IntStr: WideString; begin IntStr := ReadString(Section, ''); if (Length(IntStr) > 2) and (IntStr[1] = '0') and ((IntStr[2] = 'X') or (IntStr[2] = 'x')) then IntStr := '$' + Copy(IntStr, 3, MaxInt); Result := StrToIntDef(IntStr, Default); end; function TXMLFile.ReadIntegerValue(const Section, Attribute: WideString; Default: Integer): Integer; var IntStr: WideString; begin IntStr := ReadStringValue(Section, Attribute, ''); if (Length(IntStr) > 2) and (IntStr[1] = '0') and ((IntStr[2] = 'X') or (IntStr[2] = 'x')) then IntStr := '$' + Copy(IntStr, 3, MaxInt); Result := StrToIntDef(IntStr, Default); end; function TXMLFile.ReadString(const Section: WideString; Default: Widestring): WideString; var DOMNode: IXMLDOMNode; begin Result := Default; if FLoaded and Assigned(FXMLPage) then begin DOMNode := FXMLPage.selectSingleNode(Section); if Assigned(DOMNode) then Result := DOMNode.text; end; end; function TXMLFile.ReadStringValue(const Section, Attribute: WideString; Default: Widestring): WideString; var DOMNode, DOMAttr: IXMLDOMNode; DOMAttrs: IXMLDOMNamedNodeMap; begin Result := Default; if FLoaded and Assigned(FXMLPage) then begin DOMNode := FXMLPage.selectSingleNode(Section); if Assigned(DOMNode) then begin DOMAttrs := DOMNode.attributes; DOMAttr := DOMAttrs.getNamedItem(Attribute); if Assigned(DOMAttr) then Result := DOMAttr.text; end; end; end; function TXMLFile.ReadTime(const Section: WideString; Default: TDateTime): TDateTime; var TimeStr: string; SaveThousandSeparator, SaveDecimalSeparator: Char; begin TimeStr := ReadString(Section, ''); Result := Default; if TimeStr <> '' then try SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; Result := StrToTime(TimeStr); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; except on EConvertError do // Ignore EConvertError exceptions else raise; end; end; procedure TXMLFile.ReadVaules(const Section: WideString; Values: TStrings); var List: IXMLDOMNodeList; Node: IXMLDOMNode; Index: Integer; begin if Loaded and Assigned(XMLPage) and Assigned(Values) then begin List := XMLPage.selectNodes(Section); if Assigned(List) then for Index := 0 to List.length - 1 do begin Node := List.item[Index]; if Assigned(Node) then begin if Assigned(Node) then Values.Add(Node.text); //Values.Add(UTF8Encode(Node.text)); end; end; end; end; procedure TXMLFile.SaveToFile(const FileName: string); begin if Assigned(FXMLPage) then FXMLPage.save(FileName); end; function TXMLFile.SectionExists(const Section: WideString): Boolean; var DOMNode: IXMLDOMNode; begin Result := False; if FLoaded and Assigned(FXMLPage) then begin DOMNode := FXMLPage.selectSingleNode(Section); Result := Assigned(DOMNode); end; end; procedure TXMLFile.UpdateFile; begin //if FLoaded and Assigned(FXMLPage) then if Assigned(FXMLPage) then FXMLPage.save(FFileName); end; function TXMLFile.ValueExists(const Section: WideString): Boolean; var DOMNode: IXMLDOMNode; begin Result := False; if FLoaded and Assigned(FXMLPage) then begin DOMNode := FXMLPage.selectSingleNode(Section); Result := Assigned(DOMNode); end; end; procedure TXMLFile.WriteBool(const Section: WideString; const Value: Boolean); const Values: array[Boolean] of string = ('0', '1'); begin WriteString(Section, Values[Value]); end; procedure TXMLFile.WriteBoolValue(const Section, Attribute: WideString; const Value: Boolean); const Values: array[Boolean] of string = ('0', '1'); begin WriteStringValue(Section, Attribute, Values[Value]); end; procedure TXMLFile.WriteDate(const Section: WideString; const Value: TDateTime); var SaveThousandSeparator, SaveDecimalSeparator: Char; begin SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; WriteString(Section, DateToStr(Value)); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; end; procedure TXMLFile.WriteDateTime(const Section: WideString; const Value: TDateTime); var SaveThousandSeparator, SaveDecimalSeparator: Char; begin SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; WriteString(Section, DateTimeToStr(Value)); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; end; procedure TXMLFile.WriteFloat(const Section: WideString; const Value: Double); var SaveThousandSeparator, SaveDecimalSeparator: Char; begin SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; WriteString(Section, FloatToStr(Value)); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; end; procedure TXMLFile.WriteInteger(const Section: WideString; const Value: Integer); begin WriteString(Section, IntToStr(Value)); end; procedure TXMLFile.WriteIntegerValue(const Section, Attribute: WideString; const Value: Integer); begin WriteStringValue(Section, Attribute, IntToStr(Value)); end; procedure TXMLFile.WriteString(const Section, Value: Widestring); var DOMNode: IXMLDOMNode; begin if FLoaded and Assigned(FXMLPage) then begin DOMNode := FXMLPage.selectSingleNode(Section); if Assigned(DOMNode) then DOMNode.text := Value; end; end; function TXMLFile.WriteStringValue(const Section, Attribute, Value: Widestring): WideString; var DOMNode, DOMAttr: IXMLDOMNode; DOMAttrs: IXMLDOMNamedNodeMap; begin if FLoaded and Assigned(FXMLPage) then begin DOMNode := FXMLPage.selectSingleNode(Section); if Assigned(DOMNode) then begin DOMAttrs := DOMNode.attributes; DOMAttr := DOMAttrs.getNamedItem(Attribute); if Assigned(DOMAttr) then DOMAttr.text := Value; end; end; end; procedure TXMLFile.WriteTime(const Section: WideString; const Value: TDateTime); var SaveThousandSeparator, SaveDecimalSeparator: Char; begin SaveThousandSeparator := ThousandSeparator; SaveDecimalSeparator := DecimalSeparator; try ThousandSeparator := ','; DecimalSeparator := '.'; WriteString(Section, TimeToStr(Value)); finally ThousandSeparator := SaveThousandSeparator; DecimalSeparator := SaveDecimalSeparator; end; end; end.