xmlcfg.pp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. {
  2. $Id$
  3. This file is part of the Free Component Library
  4. Implementation of TXMLConfig class
  5. Copyright (c) 1999 - 2001 by Sebastian Guenther, [email protected]
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {
  13. TXMLConfig enables applications to use XML files for storing their
  14. configuration data
  15. }
  16. {$MODE objfpc}
  17. {$H+}
  18. unit XMLCfg;
  19. interface
  20. uses Classes, DOM, XMLRead, XMLWrite;
  21. type
  22. {"APath" is the path and name of a value: A XML configuration file is
  23. hierarchical. "/" is the path delimiter, the part after the last "/"
  24. is the name of the value. The path components will be mapped to XML
  25. elements, the name will be an element attribute.}
  26. TXMLConfig = class(TComponent)
  27. private
  28. FFilename: String;
  29. procedure SetFilename(const AFilename: String);
  30. protected
  31. doc: TXMLDocument;
  32. FModified: Boolean;
  33. procedure Loaded; override;
  34. public
  35. constructor Create(const AFilename: String);
  36. destructor Destroy; override;
  37. procedure Flush; // Writes the XML file
  38. function GetValue(const APath, ADefault: String): String;
  39. function GetValue(const APath: String; ADefault: Integer): Integer;
  40. function GetValue(const APath: String; ADefault: Boolean): Boolean;
  41. procedure SetValue(const APath, AValue: String);
  42. procedure SetValue(const APath: String; AValue: Integer);
  43. procedure SetValue(const APath: String; AValue: Boolean);
  44. property Modified: Boolean read FModified;
  45. published
  46. property Filename: String read FFilename write SetFilename;
  47. end;
  48. // ===================================================================
  49. implementation
  50. uses SysUtils;
  51. constructor TXMLConfig.Create(const AFilename: String);
  52. begin
  53. inherited Create(nil);
  54. SetFilename(AFilename);
  55. end;
  56. destructor TXMLConfig.Destroy;
  57. begin
  58. if Assigned(doc) then
  59. begin
  60. Flush;
  61. doc.Free;
  62. end;
  63. inherited Destroy;
  64. end;
  65. procedure TXMLConfig.Flush;
  66. var
  67. f: Text;
  68. begin
  69. if Modified then
  70. begin
  71. AssignFile(f, Filename);
  72. Rewrite(f);
  73. try
  74. WriteXMLFile(doc, f);
  75. finally
  76. CloseFile(f);
  77. end;
  78. FModified := False;
  79. end;
  80. end;
  81. function TXMLConfig.GetValue(const APath, ADefault: String): String;
  82. var
  83. Node, Child, Attr: TDOMNode;
  84. i: Integer;
  85. NodePath: String;
  86. begin
  87. Node := doc.DocumentElement;
  88. NodePath := APath;
  89. while True do
  90. begin
  91. i := Pos('/', NodePath);
  92. if i = 0 then
  93. break;
  94. Child := Node.FindNode(Copy(NodePath, 1, i - 1));
  95. NodePath := Copy(NodePath, i + 1, Length(NodePath));
  96. if not Assigned(Child) then
  97. begin
  98. Result := ADefault;
  99. exit;
  100. end;
  101. Node := Child;
  102. end;
  103. Attr := Node.Attributes.GetNamedItem(NodePath);
  104. if Assigned(Attr) then
  105. Result := Attr.NodeValue
  106. else
  107. Result := ADefault;
  108. end;
  109. function TXMLConfig.GetValue(const APath: String; ADefault: Integer): Integer;
  110. begin
  111. Result := StrToInt(GetValue(APath, IntToStr(ADefault)));
  112. end;
  113. function TXMLConfig.GetValue(const APath: String; ADefault: Boolean): Boolean;
  114. var
  115. s: String;
  116. begin
  117. if ADefault then
  118. s := 'True'
  119. else
  120. s := 'False';
  121. s := GetValue(APath, s);
  122. if UpperCase(s) = 'TRUE' then
  123. Result := True
  124. else if UpperCase(s) = 'FALSE' then
  125. Result := False
  126. else
  127. Result := ADefault;
  128. end;
  129. procedure TXMLConfig.SetValue(const APath, AValue: String);
  130. var
  131. Node, Child, Attr: TDOMNode;
  132. i: Integer;
  133. NodeName, NodePath: String;
  134. begin
  135. Node := Doc.DocumentElement;
  136. NodePath := APath;
  137. while True do
  138. begin
  139. i := Pos('/', NodePath);
  140. if i = 0 then
  141. break;
  142. NodeName := Copy(NodePath, 1, i - 1);
  143. NodePath := Copy(NodePath, i + 1, Length(NodePath));
  144. Child := Node.FindNode(NodeName);
  145. if not Assigned(Child) then
  146. begin
  147. Child := Doc.CreateElement(NodeName);
  148. Node.AppendChild(Child);
  149. end;
  150. Node := Child;
  151. end;
  152. if (not Assigned(TDOMElement(Node).GetAttributeNode(NodePath))) or
  153. (TDOMElement(Node)[NodePath] <> AValue) then
  154. begin
  155. TDOMElement(Node)[NodePath] := AValue;
  156. FModified := True;
  157. end;
  158. end;
  159. procedure TXMLConfig.SetValue(const APath: String; AValue: Integer);
  160. begin
  161. SetValue(APath, IntToStr(AValue));
  162. end;
  163. procedure TXMLConfig.SetValue(const APath: String; AValue: Boolean);
  164. begin
  165. if AValue then
  166. SetValue(APath, 'True')
  167. else
  168. SetValue(APath, 'False');
  169. end;
  170. procedure TXMLConfig.Loaded;
  171. begin
  172. inherited Loaded;
  173. if Length(Filename) > 0 then
  174. SetFilename(Filename); // Load the XML config file
  175. end;
  176. procedure TXMLConfig.SetFilename(const AFilename: String);
  177. var
  178. f: File;
  179. cfg: TDOMElement;
  180. begin
  181. FFilename := AFilename;
  182. if csLoading in ComponentState then
  183. exit;
  184. if Assigned(doc) then
  185. begin
  186. Flush;
  187. doc.Free;
  188. end;
  189. AssignFile(f, AFileName);
  190. {$I-}
  191. Reset(f, 1);
  192. {$I+}
  193. if IOResult = 0 then
  194. try
  195. ReadXMLFile(doc, f);
  196. finally
  197. CloseFile(f);
  198. end;
  199. if not Assigned(doc) then
  200. doc := TXMLDocument.Create;
  201. cfg :=TDOMElement(doc.FindNode('CONFIG'));
  202. if not Assigned(cfg) then begin
  203. cfg := doc.CreateElement('CONFIG');
  204. doc.AppendChild(cfg);
  205. end;
  206. end;
  207. end.
  208. {
  209. $Log$
  210. Revision 1.5 2002-09-07 15:15:29 peter
  211. * old logs removed and tabs fixed
  212. }