xmlwrite.pp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. {
  2. $Id$
  3. This file is part of the Free Component Library
  4. Copyright (c) 1999-2000 by Sebastian Guenther
  5. XML writing routines
  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. {$MODE objfpc}
  13. {$H+}
  14. unit xmlwrite;
  15. interface
  16. uses classes, DOM;
  17. procedure WriteXMLFile(doc: TXMLDocument; const AFileName: String);
  18. procedure WriteXMLFile(doc: TXMLDocument; var AFile: Text);
  19. procedure WriteXMLFile(doc: TXMLDocument; var AStream: TStream);
  20. // =======================================================
  21. implementation
  22. // -------------------------------------------------------
  23. // Writers for the different node types
  24. // -------------------------------------------------------
  25. procedure WriteElement(node: TDOMNode); forward;
  26. procedure WriteAttribute(node: TDOMNode); forward;
  27. procedure WriteText(node: TDOMNode); forward;
  28. procedure WriteCDATA(node: TDOMNode); forward;
  29. procedure WriteEntityRef(node: TDOMNode); forward;
  30. procedure WriteEntity(node: TDOMNode); forward;
  31. procedure WritePI(node: TDOMNode); forward;
  32. procedure WriteComment(node: TDOMNode); forward;
  33. procedure WriteDocument(node: TDOMNode); forward;
  34. procedure WriteDocumentType(node: TDOMNode); forward;
  35. procedure WriteDocumentFragment(node: TDOMNode); forward;
  36. procedure WriteNotation(node: TDOMNode); forward;
  37. type
  38. TWriteNodeProc = procedure(node: TDOMNode);
  39. const
  40. WriteProcs: array[ELEMENT_NODE..NOTATION_NODE] of TWriteNodeProc =
  41. (WriteElement, WriteAttribute, WriteText, WriteCDATA, WriteEntityRef,
  42. WriteEntity, WritePI, WriteComment, WriteDocument, WriteDocumentType,
  43. WriteDocumentFragment, WriteNotation);
  44. procedure WriteNode(node: TDOMNode);
  45. begin
  46. WriteProcs[node.NodeType](node);
  47. end;
  48. // -------------------------------------------------------
  49. // Text file and TStream support
  50. // -------------------------------------------------------
  51. type
  52. TOutputProc = procedure(s: String);
  53. var
  54. f: ^Text;
  55. stream: TStream;
  56. wrt, wrtln: TOutputProc;
  57. procedure Text_Write(s: String);
  58. begin
  59. Write(f^, s);
  60. end;
  61. procedure Text_WriteLn(s: String);
  62. begin
  63. WriteLn(f^, s);
  64. end;
  65. procedure Stream_Write(s: String);
  66. begin
  67. stream.Write(s[1], Length(s));
  68. end;
  69. procedure Stream_WriteLn(s: String);
  70. begin
  71. stream.Write(s[1], Length(s));
  72. stream.WriteByte(10);
  73. end;
  74. // -------------------------------------------------------
  75. // Indent handling
  76. // -------------------------------------------------------
  77. var
  78. indent: String;
  79. procedure IncIndent;
  80. begin
  81. indent := indent + ' ';
  82. end;
  83. procedure DecIndent;
  84. begin
  85. indent := Copy(indent, 1, Length(indent) - 2);
  86. end;
  87. // -------------------------------------------------------
  88. // Node writers implementations
  89. // -------------------------------------------------------
  90. procedure WriteElement(node: TDOMNode);
  91. var
  92. i: Integer;
  93. attr, child: TDOMNode;
  94. begin
  95. wrt(Indent + '<' + node.NodeName);
  96. for i := 0 to node.Attributes.Length - 1 do begin
  97. attr := node.Attributes.Item[i];
  98. wrt(' ' + attr.NodeName + '="' + attr.NodeValue + '"');
  99. end;
  100. child := node.FirstChild;
  101. if child = nil then
  102. wrtln('/>')
  103. else begin
  104. wrtln('>');
  105. IncIndent;
  106. repeat
  107. WriteNode(child);
  108. child := child.NextSibling;
  109. until child = nil;
  110. DecIndent;
  111. wrtln(Indent + '</' + node.NodeName + '>');
  112. end;
  113. end;
  114. procedure WriteAttribute(node: TDOMNode);
  115. begin
  116. WriteLn('WriteAttribute');
  117. end;
  118. procedure WriteText(node: TDOMNode);
  119. begin
  120. wrt(node.NodeValue);
  121. end;
  122. procedure WriteCDATA(node: TDOMNode);
  123. begin
  124. wrtln('<![CDATA[' + node.NodeValue + ']]>');
  125. end;
  126. procedure WriteEntityRef(node: TDOMNode);
  127. begin
  128. wrt('&' + node.NodeValue + ';');
  129. end;
  130. procedure WriteEntity(node: TDOMNode);
  131. begin
  132. WriteLn('WriteEntity');
  133. end;
  134. procedure WritePI(node: TDOMNode);
  135. begin
  136. WriteLn('WritePI');
  137. end;
  138. procedure WriteComment(node: TDOMNode);
  139. begin
  140. Write('<!--', node.NodeValue, '-->');
  141. end;
  142. procedure WriteDocument(node: TDOMNode);
  143. begin
  144. WriteLn('WriteDocument');
  145. end;
  146. procedure WriteDocumentType(node: TDOMNode);
  147. begin
  148. WriteLn('WriteDocumentType');
  149. end;
  150. procedure WriteDocumentFragment(node: TDOMNode);
  151. begin
  152. WriteLn('WriteDocumentFragment');
  153. end;
  154. procedure WriteNotation(node: TDOMNode);
  155. begin
  156. WriteLn('WriteNotation');
  157. end;
  158. procedure RootWriter(doc: TXMLDocument);
  159. var
  160. child: TDOMNode;
  161. begin
  162. wrt('<?xml version="');
  163. if doc.XMLVersion <> '' then wrt(doc.XMLVersion)
  164. else wrt('1.0');
  165. wrt('"');
  166. if doc.Encoding <> '' then wrt(' encoding="' + doc.Encoding + '"');
  167. wrtln('?>');
  168. indent := '';
  169. child := doc.FirstChild;
  170. while child <> nil do begin
  171. WriteNode(child);
  172. child := child.NextSibling;
  173. end;
  174. end;
  175. // -------------------------------------------------------
  176. // Interface implementation
  177. // -------------------------------------------------------
  178. procedure WriteXMLFile(doc: TXMLDocument; var AFile: Text);
  179. begin
  180. f := @AFile;
  181. wrt := @Text_Write;
  182. wrtln := @Text_WriteLn;
  183. RootWriter(doc);
  184. end;
  185. procedure WriteXMLFile(doc: TXMLDocument; var AStream: TStream);
  186. begin
  187. stream := AStream;
  188. wrt := @Stream_Write;
  189. wrtln := @Stream_WriteLn;
  190. RootWriter(doc);
  191. end;
  192. procedure WriteXMLFile(doc: TXMLDocument; const AFileName: String);
  193. var
  194. stream: TFileStream;
  195. begin
  196. stream := TFileStream.Create(AFileName, fmCreate);
  197. WriteXMLFile(doc, stream);
  198. stream.Free;
  199. end;
  200. end.
  201. {
  202. $Log$
  203. Revision 1.6 2000-01-07 01:24:34 peter
  204. * updated copyright to 2000
  205. Revision 1.5 2000/01/06 01:20:37 peter
  206. * moved out of packages/ back to topdir
  207. Revision 1.1 2000/01/03 19:33:12 peter
  208. * moved to packages dir
  209. Revision 1.3 1999/07/22 15:06:35 michael
  210. * Fix for stream_write from Sebastian Guenther
  211. Revision 1.2 1999/07/09 21:05:53 michael
  212. + fixes from Guenther Sebastian
  213. Revision 1.1 1999/07/09 08:35:09 michael
  214. + Initial implementation by Sebastian Guenther
  215. }