xmlwrite.pp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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.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.3 1999-07-22 15:06:35 michael
  204. * Fix for stream_write from Sebastian Guenther
  205. Revision 1.2 1999/07/09 21:05:53 michael
  206. + fixes from Guenther Sebastian
  207. Revision 1.1 1999/07/09 08:35:09 michael
  208. + Initial implementation by Sebastian Guenther
  209. }