xmlwrite.pp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999 Sebastian Guenther, [email protected]
  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.WriteAnsiString(s);
  68. end;
  69. procedure Stream_WriteLn(s: String);
  70. begin
  71. stream.WriteAnsiString(s + #10);
  72. end;
  73. // -------------------------------------------------------
  74. // Indent handling
  75. // -------------------------------------------------------
  76. var
  77. indent: String;
  78. procedure IncIndent;
  79. begin
  80. indent := indent + ' ';
  81. end;
  82. procedure DecIndent;
  83. begin
  84. indent := Copy(indent, 1, Length(indent) - 2);
  85. end;
  86. // -------------------------------------------------------
  87. // Node writers implementations
  88. // -------------------------------------------------------
  89. procedure WriteElement(node: TDOMNode);
  90. var
  91. i: Integer;
  92. attr, child: TDOMNode;
  93. begin
  94. wrt(Indent + '<' + node.NodeName);
  95. for i := 0 to node.Attributes.Length - 1 do begin
  96. attr := node.Attributes.Item[i];
  97. wrt(' ' + attr.NodeName + '="' + attr.NodeValue + '"');
  98. end;
  99. child := node.FirstChild;
  100. if child = nil then
  101. wrtln('/>')
  102. else begin
  103. wrtln('>');
  104. IncIndent;
  105. repeat
  106. WriteNode(child);
  107. child := child.NextSibling;
  108. until child = nil;
  109. DecIndent;
  110. wrtln(Indent + '</' + node.NodeName + '>');
  111. end;
  112. end;
  113. procedure WriteAttribute(node: TDOMNode);
  114. begin
  115. WriteLn('WriteAttribute');
  116. end;
  117. procedure WriteText(node: TDOMNode);
  118. begin
  119. wrt(node.NodeValue);
  120. end;
  121. procedure WriteCDATA(node: TDOMNode);
  122. begin
  123. wrtln('<![CDATA[' + node.NodeValue + ']]>');
  124. end;
  125. procedure WriteEntityRef(node: TDOMNode);
  126. begin
  127. wrt('&' + node.NodeValue + ';');
  128. end;
  129. procedure WriteEntity(node: TDOMNode);
  130. begin
  131. WriteLn('WriteEntity');
  132. end;
  133. procedure WritePI(node: TDOMNode);
  134. begin
  135. WriteLn('WritePI');
  136. end;
  137. procedure WriteComment(node: TDOMNode);
  138. begin
  139. Write('<!--', node.NodeValue, '-->');
  140. end;
  141. procedure WriteDocument(node: TDOMNode);
  142. begin
  143. WriteLn('WriteDocument');
  144. end;
  145. procedure WriteDocumentType(node: TDOMNode);
  146. begin
  147. WriteLn('WriteDocumentType');
  148. end;
  149. procedure WriteDocumentFragment(node: TDOMNode);
  150. begin
  151. WriteLn('WriteDocumentFragment');
  152. end;
  153. procedure WriteNotation(node: TDOMNode);
  154. begin
  155. WriteLn('WriteNotation');
  156. end;
  157. procedure RootWriter(doc: TXMLDocument);
  158. var
  159. child: TDOMNode;
  160. begin
  161. wrt('<?xml version="');
  162. if doc.XMLVersion <> '' then wrt(doc.XMLVersion)
  163. else wrt('1.0');
  164. wrt('"');
  165. if doc.Encoding <> '' then wrt(' encoding="' + doc.Encoding + '"');
  166. wrtln('?>');
  167. indent := '';
  168. child := doc.FirstChild;
  169. while child <> nil do begin
  170. WriteNode(child);
  171. child := child.NextSibling;
  172. end;
  173. end;
  174. // -------------------------------------------------------
  175. // Interface implementation
  176. // -------------------------------------------------------
  177. procedure WriteXMLFile(doc: TXMLDocument; var AFile: Text);
  178. begin
  179. f := @AFile;
  180. wrt := @Text_Write;
  181. wrtln := @Text_WriteLn;
  182. RootWriter(doc);
  183. end;
  184. procedure WriteXMLFile(doc: TXMLDocument; var AStream: TStream);
  185. begin
  186. stream := AStream;
  187. wrt := @Stream_Write;
  188. wrtln := @Stream_WriteLn;
  189. RootWriter(doc);
  190. end;
  191. procedure WriteXMLFile(doc: TXMLDocument; const AFileName: String);
  192. var
  193. stream: TFileStream;
  194. begin
  195. stream := TFileStream.Create(AFileName, fmCreate);
  196. WriteXMLFile(doc, stream);
  197. stream.Free;
  198. end;
  199. end.
  200. {
  201. $Log$
  202. Revision 1.2 1999-07-09 21:05:53 michael
  203. + fixes from Guenther Sebastian
  204. Revision 1.1 1999/07/09 08:35:09 michael
  205. + Initial implementation by Sebastian Guenther
  206. }