xmlcfg.pp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999 Sebastian Guenther, [email protected]
  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 doc = nil then
  64. doc := TXMLDocument.Create;
  65. cfg :=TDOMElement(doc.FindNode('CONFIG'));
  66. if cfg = nil then begin
  67. cfg := doc.CreateElement('CONFIG');
  68. doc.AppendChild(cfg);
  69. end;
  70. doc.SetDocumentElement(cfg);
  71. end;
  72. destructor TXMLConfig.Destroy;
  73. begin
  74. Flush;
  75. inherited Destroy;
  76. end;
  77. procedure TXMLConfig.Flush;
  78. var
  79. f: Text;
  80. begin
  81. Assign(f, FileName);
  82. Rewrite(f);
  83. WriteXMLFile(doc, f);
  84. Close(f);
  85. end;
  86. function TXMLConfig.GetValue(const APath, ADefault: String): String;
  87. var
  88. node, subnode, attr: TDOMNode;
  89. i: Integer;
  90. name, path: String;
  91. begin
  92. node := doc.DocumentElement;
  93. path := APath;
  94. while True do begin
  95. i := Pos('/', path);
  96. if i = 0 then break;
  97. name := Copy(path, 1, i - 1);
  98. path := Copy(path, i + 1, Length(path));
  99. subnode := node.FindNode(name);
  100. if subnode = nil then begin
  101. Result := ADefault;
  102. exit;
  103. end;
  104. node := subnode;
  105. end;
  106. attr := node.Attributes.GetNamedItem(path);
  107. if attr = nil then
  108. Result := ADefault
  109. else
  110. Result := attr.NodeValue;
  111. end;
  112. function TXMLConfig.GetValue(const APath: String; ADefault: Integer): Integer;
  113. begin
  114. Result := StrToInt(GetValue(APath, IntToStr(ADefault)));
  115. end;
  116. function TXMLConfig.GetValue(const APath: String; ADefault: Boolean): Boolean;
  117. var
  118. s: String;
  119. begin
  120. if ADefault then
  121. s := 'True'
  122. else
  123. s := 'False';
  124. s := GetValue(APath, s);
  125. if UpperCase(s) = 'TRUE' then
  126. Result := True
  127. else if UpperCase(s) = 'FALSE' then
  128. Result := False
  129. else
  130. Result := ADefault;
  131. end;
  132. procedure TXMLConfig.SetValue(const APath, AValue: String);
  133. var
  134. node, subnode, attr: TDOMNode;
  135. i: Integer;
  136. name, path: String;
  137. begin
  138. node := doc.DocumentElement;
  139. path := APath;
  140. while True do begin
  141. i := Pos('/', path);
  142. if i = 0 then break;
  143. name := Copy(path, 1, i - 1);
  144. path := Copy(path, i + 1, Length(path));
  145. subnode := node.FindNode(name);
  146. if subnode = nil then begin
  147. subnode := doc.CreateElement(name);
  148. node.AppendChild(subnode);
  149. end;
  150. node := subnode;
  151. end;
  152. attr := node.Attributes.GetNamedItem(path);
  153. if attr = nil then begin
  154. attr := doc.CreateAttribute(path);
  155. node.Attributes.SetNamedItem(attr);
  156. end;
  157. attr.NodeValue := AValue;
  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. end.
  171. {
  172. $Log$
  173. Revision 1.4 1999-12-22 13:38:01 sg
  174. * Lots of cosmetic changes (strings -> const AnsiStrings etc.)
  175. Revision 1.3 1999/07/25 16:24:13 michael
  176. + Fixes from Sebastiam Guenther - more error-proof
  177. Revision 1.2 1999/07/09 21:05:50 michael
  178. + fixes from Guenther Sebastian
  179. Revision 1.1 1999/07/09 08:35:09 michael
  180. + Initial implementation by Sebastian Guenther
  181. }