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
Delphi

Avatar of undefined
Last Comment
coldboy

8/22/2022 - Mon
Limbeck

i dont know what error you are getting :)

take a look at:

http://www.swissdelphicenter.ch/torry/showcode.php?id=2269
TName

Why do you declare  TApplicationConfig class in the implementation section?
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
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
ASKER CERTIFIED SOLUTION
TName

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
coldboy

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