xmlcfg.pp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. {
  2. $Id$
  3. This file is part of the Free Component Library
  4. Copyright (c) 1999-2000 by Sebastian Guenther
  5. Implementation of TXMLConfig class
  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 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
  27. protected
  28. doc: TXMLDocument;
  29. FileName: String;
  30. public
  31. constructor Create(const AFileName: String);
  32. destructor Destroy; override;
  33. procedure Flush; // Writes the XML file
  34. function GetValue(const APath, ADefault: String): String;
  35. function GetValue(const APath: String; ADefault: Integer): Integer;
  36. function GetValue(const APath: String; ADefault: Boolean): Boolean;
  37. procedure SetValue(const APath, AValue: String);
  38. procedure SetValue(const APath: String; AValue: Integer);
  39. procedure SetValue(const APath: String; AValue: Boolean);
  40. end;
  41. // ===================================================================
  42. implementation
  43. uses SysUtils;
  44. constructor TXMLConfig.Create(const AFileName: String);
  45. var
  46. f: File;
  47. cfg: TDOMElement;
  48. begin
  49. FileName := AFileName;
  50. Assign(f, AFileName);
  51. {$I-}
  52. Reset(f, 1);
  53. {$I+}
  54. if IOResult = 0 then begin
  55. try
  56. ReadXMLFile(doc, f);
  57. except
  58. on e: EXMLReadError do
  59. WriteLn(StdErr, 'Warning: XML config parsing error: ', e.Message);
  60. end;
  61. Close(f);
  62. end;
  63. if not Assigned(doc) then
  64. doc := TXMLDocument.Create;
  65. cfg :=TDOMElement(doc.FindNode('CONFIG'));
  66. if not Assigned(cfg) then begin
  67. cfg := doc.CreateElement('CONFIG');
  68. doc.AppendChild(cfg);
  69. end;
  70. end;
  71. destructor TXMLConfig.Destroy;
  72. begin
  73. Flush;
  74. if Assigned(doc) then
  75. doc.Free;
  76. inherited Destroy;
  77. end;
  78. procedure TXMLConfig.Flush;
  79. var
  80. f: Text;
  81. begin
  82. Assign(f, FileName);
  83. Rewrite(f);
  84. WriteXMLFile(doc, f);
  85. Close(f);
  86. end;
  87. function TXMLConfig.GetValue(const APath, ADefault: String): String;
  88. var
  89. node, subnode, attr: TDOMNode;
  90. i: Integer;
  91. name, path: String;
  92. begin
  93. node := doc.DocumentElement;
  94. path := APath;
  95. while True do begin
  96. i := Pos('/', path);
  97. if i = 0 then break;
  98. name := Copy(path, 1, i - 1);
  99. path := Copy(path, i + 1, Length(path));
  100. subnode := node.FindNode(name);
  101. if not Assigned(subnode) then begin
  102. Result := ADefault;
  103. exit;
  104. end;
  105. node := subnode;
  106. end;
  107. attr := node.Attributes.GetNamedItem(path);
  108. if Assigned(attr) then
  109. Result := attr.NodeValue
  110. else
  111. Result := ADefault;
  112. end;
  113. function TXMLConfig.GetValue(const APath: String; ADefault: Integer): Integer;
  114. begin
  115. Result := StrToInt(GetValue(APath, IntToStr(ADefault)));
  116. end;
  117. function TXMLConfig.GetValue(const APath: String; ADefault: Boolean): Boolean;
  118. var
  119. s: String;
  120. begin
  121. if ADefault then
  122. s := 'True'
  123. else
  124. s := 'False';
  125. s := GetValue(APath, s);
  126. if UpperCase(s) = 'TRUE' then
  127. Result := True
  128. else if UpperCase(s) = 'FALSE' then
  129. Result := False
  130. else
  131. Result := ADefault;
  132. end;
  133. procedure TXMLConfig.SetValue(const APath, AValue: String);
  134. var
  135. node, subnode, attr: TDOMNode;
  136. i: Integer;
  137. name, path: String;
  138. begin
  139. node := doc.DocumentElement;
  140. path := APath;
  141. while True do begin
  142. i := Pos('/', path);
  143. if i = 0 then break;
  144. name := Copy(path, 1, i - 1);
  145. path := Copy(path, i + 1, Length(path));
  146. subnode := node.FindNode(name);
  147. if not Assigned(subnode) then begin
  148. subnode := doc.CreateElement(name);
  149. node.AppendChild(subnode);
  150. end;
  151. node := subnode;
  152. end;
  153. attr := node.Attributes.GetNamedItem(path);
  154. if not Assigned(attr) then begin
  155. attr := doc.CreateAttribute(path);
  156. node.Attributes.SetNamedItem(attr);
  157. end;
  158. attr.NodeValue := AValue;
  159. end;
  160. procedure TXMLConfig.SetValue(const APath: String; AValue: Integer);
  161. begin
  162. SetValue(APath, IntToStr(AValue));
  163. end;
  164. procedure TXMLConfig.SetValue(const APath: String; AValue: Boolean);
  165. begin
  166. if AValue then
  167. SetValue(APath, 'True')
  168. else
  169. SetValue(APath, 'False');
  170. end;
  171. end.
  172. {
  173. $Log$
  174. Revision 1.9 2000-02-13 10:03:31 sg
  175. * Hopefully final fix for TDOMDocument.DocumentElement:
  176. - Reading this property always delivers the first element in the document
  177. - Removed SetDocumentElement. Use "AppendChild" or one of the other
  178. generic methods for TDOMNode instead.
  179. Revision 1.8 2000/01/30 22:20:08 sg
  180. * TXMLConfig now frees its XML document (major memory leak...)
  181. Revision 1.7 2000/01/07 01:24:34 peter
  182. * updated copyright to 2000
  183. Revision 1.6 2000/01/06 01:20:37 peter
  184. * moved out of packages/ back to topdir
  185. Revision 1.1 2000/01/03 19:33:11 peter
  186. * moved to packages dir
  187. Revision 1.4 1999/12/22 13:38:01 sg
  188. * Lots of cosmetic changes (strings -> const AnsiStrings etc.)
  189. Revision 1.3 1999/07/25 16:24:13 michael
  190. + Fixes from Sebastiam Guenther - more error-proof
  191. Revision 1.2 1999/07/09 21:05:50 michael
  192. + fixes from Guenther Sebastian
  193. Revision 1.1 1999/07/09 08:35:09 michael
  194. + Initial implementation by Sebastian Guenther
  195. }