Link to home
Start Free TrialLog in
Avatar of coldboy
coldboy

asked on

Problem in working with XML file

Hi!
I have some problem with XML file.
I want to built a application that be able to save it's configuration in to a xml file.
So I built a class named TApplicationConfig that can work with XML file.
But When I call GetProperty method of this class, an Error appears and I don't understand why error!
Have a look at my code:
-----------------------------------------------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
uses XMLDoc, XmlIntf;
{$R *.dfm}

type
  TApplicationConfig = class(TObject)
  protected
    FXml: TXMLDocument;
    function GetProperty(Name: WideString): WideString;
    procedure SetProperty(Name: WideString; Value: WideString);
  public
    Constructor Create(XmlFileName: String);
    Destructor Destroy; override;
    property _Property[Name: WideString]: WideString read GetProperty write SetProperty;
  end;

constructor TApplicationConfig.Create(XmlFileName: String);
var
  Str: TStrings;
  Msg: String;
begin
  FXml:= TXMLDocument.Create(nil);
  FXml.FileName:= XmlFileName;
  Try
    FXml.Active:= True
  except
    FXml.Active:= False;
    Str:= TStringList.Create;
    Str.Add('<?xml version="1.0" encoding="UTF-8"?>');
    Str.Add('<CONFIG>');
    Str.Add('</CONFIG>');
    try
      Str.SaveToFile(XmlFileName);
      FXml.Active:= True;
    except
      FXml.Active:= False;
      Msg:= Format('Unable to load config from file %s. Access denied ',[XmlFilename]);
      MessageBox(Application.Handle, Pchar(Msg), 'Error', MB_OK OR MB_ICONERROR);
    end;
    Str.Free;
  end;
end;

destructor TApplicationConfig.Destroy;
var Msg: String;
begin
  if FXml.Active then
    Try
      FXml.SaveToFile(FXml.FileName);
    Except
      Msg:= Format('Unable to write config to file %s. Access denied', [FXml.FileName]);
      MessageBox(Application.Handle, PChar(Msg), 'Error', MB_OK OR MB_ICONERROR);
    end;
  FXml.Active:= False;
  FXml.Free;
  inherited;
end;

function TApplicationConfig.GetProperty(Name: WideString): WideString;
var
  c1: integer;
  Root: IXmlNode;
begin
  if FXml.Active then begin
    Root:= FXml.DocumentElement;
    for c1:= 0 to Root.ChildNodes.Count-1 do
      if AnsiCompareStr(Name, Root.ChildNodes[c1].NodeName)=0 then begin
        Result:= Root.ChildNodes[c1].NodeValue;
        Exit;
      end;
  end else Result:= '';
end;

procedure TApplicationConfig.SetProperty(Name: WideString; Value: WideString);
var
  c1: integer;
  Node: IXmlNode;
  Root: IXmlNode;
begin
  if FXml.Active then begin
    Root:= FXml.DocumentElement;
    for c1:= 0 to Root.ChildNodes.Count-1 do
      if AnsiCompareStr(Name, Root.ChildNodes[c1].NodeName)=0 then begin
        Root.ChildNodes[c1].NodeValue:= Value;
        Exit;
      end;
    Node:= FXml.CreateElement(Name, EmptyParam);
    Node.NodeValue:= Value;
    Root.ChildNodes.Add(Node);
  end;
end;

var AppCfg: TApplicationConfig;
procedure TForm1.FormCreate(Sender: TObject);
begin
  AppCfg:= TApplicationConfig.Create('D:\test.xml');
  ShowMessage(AppCfg._Property['LANG']);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  AppCfg.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  AppCfg._Property['LANG']:= 'Hehehe';
end;

end.
--------------------------------End------
Thanks for care.
coldboyqn
Avatar of Limbeck
Limbeck

i dont know what error you are getting :)

take a look at:

http://www.swissdelphicenter.ch/torry/showcode.php?id=2269
Why do you declare  TApplicationConfig class in the implementation section?
Avatar of coldboy

ASKER

Hi!
I found a way to fix my problem, but I don't understand why can this way can fix it.
I change from FXml:= TXmlDocument.Create(nil) in to Fxml:= TXmlDocument.Create(Application).

There still a minor problem because EmptyParam cannot be a parameter of XmlDocument.CreateElement so I change to empty String (Node:= FXml.CreateElement(Name, '').

I will give all points to who explain me why replacing Application for nil as parameter of TxmlDocument.Create can avoid error.

Thanks for care.
coldboyqn
ASKER CERTIFIED SOLUTION
Avatar of TName
TName

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of coldboy

ASKER

OK, thanks you, I understand now.
Points for you.
Regard
coldboyqn