testWriter.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206
  1. (**
  2. * section: xmlWriter
  3. * synopsis: use various APIs for the xmlWriter
  4. * purpose: tests a number of APIs for the xmlWriter, especially
  5. * the various methods to write to a filename, to a memory
  6. * buffer, to a new document, or to a subtree. It shows how to
  7. * do encoding string conversions too. The resulting
  8. * documents are then serialized.
  9. * usage: testWriter
  10. * test: testWriter && for i in 1 2 3 4 ; do diff $(srcdir)/writer.xml writer$$i.tmp || break ; done
  11. * author: Alfred Mickautsch
  12. * copy: see Copyright for the status of this software.
  13. *)
  14. program testWriter;
  15. {$mode objfpc}
  16. uses
  17. ctypes,
  18. xml2,
  19. exutils,
  20. SysUtils,
  21. Strings;
  22. const
  23. MY_ENCODING = 'ISO-8859-1';
  24. (**
  25. * ConvertInput:
  26. * @in: string in a given encoding
  27. * @encoding: the encoding used
  28. *
  29. * Converts @in into UTF-8 for processing with libxml2 APIs
  30. *
  31. * Returns the converted UTF-8 string, or NULL in case of error.
  32. *)
  33. function ConvertInput(const inp, encoding: PAnsiChar): xmlCharPtr;
  34. var
  35. ret: cint;
  36. size: cint;
  37. out_size: cint;
  38. temp: cint;
  39. handler: xmlCharEncodingHandlerPtr;
  40. begin
  41. Result := Nil;
  42. if inp = Nil then
  43. Exit;
  44. handler := xmlFindCharEncodingHandler(encoding);
  45. if handler = Nil then
  46. begin
  47. printfn('ConvertInput: no encoding handler found for ''%s''',
  48. [specialize IfThen<PAnsiChar>(encoding <> Nil, encoding, '')]);
  49. Exit;
  50. end;
  51. size := strlen(inp) + 1;
  52. out_size := size * 2 - 1;
  53. Result := xmlCharPtr(xmlMalloc(out_size));
  54. if Result <> nil then
  55. begin
  56. temp := size - 1;
  57. ret := handler^.input(Result, @out_size, inp, @temp);
  58. if (ret < 0) or (temp - size + 1 <> 0) then
  59. begin
  60. if ret < 0 then
  61. printfn('ConvertInput: conversion wasn''t successful.')
  62. else
  63. printfn('ConvertInput: conversion wasn''t successful. converted: %i octets.',
  64. [temp]);
  65. xmlFree(Result);
  66. Result := Nil;
  67. end else
  68. begin
  69. Result := xmlCharPtr(xmlRealloc(Result, out_size + 1));
  70. Result[out_size] := #0; (*null terminating out *)
  71. end;
  72. end else
  73. printf('ConvertInput: no mem');
  74. end;
  75. (**
  76. * testXmlwriterFilename:
  77. * @uri: the output URI
  78. *
  79. * test the xmlWriter interface when writing to a new file
  80. *)
  81. procedure testXmlwriterFilename(const uri: PAnsiChar);
  82. var
  83. rc: cint;
  84. writer: xmlTextWriterPtr;
  85. tmp: xmlCharPtr;
  86. begin
  87. (* Create a new XmlWriter for uri, with no compression. *)
  88. writer := xmlNewTextWriterFilename(uri, 0);
  89. if writer = Nil then
  90. begin
  91. printfn('testXmlwriterFilename: Error creating the xml writer');
  92. Exit;
  93. end;
  94. (* Start the document with the xml default for the version,
  95. * encoding ISO 8859-1 and the default for the standalone
  96. * declaration. *)
  97. rc := xmlTextWriterStartDocument(writer, Nil, MY_ENCODING, Nil);
  98. if rc < 0 then
  99. begin
  100. printfn('testXmlwriterFilename: Error at xmlTextWriterStartDocument');
  101. Exit;
  102. end;
  103. (* Start an element named "EXAMPLE". Since thist is the first
  104. * element, this will be the root element of the document. *)
  105. rc := xmlTextWriterStartElement(writer, 'EXAMPLE');
  106. if rc < 0 then
  107. begin
  108. printfn('testXmlwriterFilename: Error at xmlTextWriterStartElement');
  109. Exit;
  110. end;
  111. (* Write a comment as child of EXAMPLE.
  112. * Please observe, that the input to the xmlTextWriter functions
  113. * HAS to be in UTF-8, even if the output XML is encoded
  114. * in iso-8859-1 *)
  115. tmp := ConvertInput('This is a comment with special chars: <'#$E4#$F6#$FC'>',
  116. MY_ENCODING);
  117. rc := xmlTextWriterWriteComment(writer, tmp);
  118. if rc < 0 then
  119. begin
  120. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteComment');
  121. Exit;
  122. end;
  123. if tmp <> Nil then
  124. xmlFree(tmp);
  125. (* Start an element named "ORDER" as child of EXAMPLE. *)
  126. rc := xmlTextWriterStartElement(writer, 'ORDER');
  127. if rc < 0 then
  128. begin
  129. printfn('testXmlwriterFilename: Error at xmlTextWriterStartElement');
  130. Exit;
  131. end;
  132. (* Add an attribute with name "version" and value "1.0" to ORDER. *)
  133. rc := xmlTextWriterWriteAttribute(writer, 'version', '1.0');
  134. if rc < 0 then
  135. begin
  136. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteAttribute');
  137. Exit;
  138. end;
  139. (* Add an attribute with name "xml:lang" and value "de" to ORDER. *)
  140. rc := xmlTextWriterWriteAttribute(writer, 'xml:lang', 'de');
  141. if rc < 0 then
  142. begin
  143. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteAttribute');
  144. Exit;
  145. end;
  146. (* Write a comment as child of ORDER *)
  147. tmp := ConvertInput('<'#$E4#$F6#$FC'>', MY_ENCODING);
  148. rc := xmlTextWriterWriteFormatComment(writer,
  149. 'This is another comment with special chars: %s', [tmp]);
  150. if (rc < 0) then
  151. begin
  152. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteFormatComment');
  153. Exit;
  154. end;
  155. if tmp <> Nil then
  156. xmlFree(tmp);
  157. (* Start an element named "HEADER" as child of ORDER. *)
  158. rc := xmlTextWriterStartElement(writer, 'HEADER');
  159. if rc < 0 then
  160. begin
  161. printfn('testXmlwriterFilename: Error at xmlTextWriterStartElement');
  162. Exit;
  163. end;
  164. (* Write an element named "X_ORDER_ID" as child of HEADER. *)
  165. rc := xmlTextWriterWriteFormatElement(writer, 'X_ORDER_ID', '%010d', [53535]);
  166. if rc < 0 then
  167. begin
  168. printf('testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement');
  169. Exit;
  170. end;
  171. (* Write an element named "CUSTOMER_ID" as child of HEADER. *)
  172. rc := xmlTextWriterWriteFormatElement(writer, 'CUSTOMER_ID', '%d', [1010]);
  173. if rc < 0 then
  174. begin
  175. printf('testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement');
  176. Exit;
  177. end;
  178. (* Write an element named "NAME_1" as child of HEADER. *)
  179. tmp := ConvertInput('M'#$FC'ller', MY_ENCODING);
  180. rc := xmlTextWriterWriteElement(writer, 'NAME_1', tmp);
  181. if rc < 0 then
  182. begin
  183. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteElement');
  184. Exit;
  185. end;
  186. if tmp <> Nil then
  187. xmlFree(tmp);
  188. (* Write an element named "NAME_2" as child of HEADER. *)
  189. tmp := ConvertInput('J'#$F6'rg', MY_ENCODING);
  190. rc := xmlTextWriterWriteElement(writer, 'NAME_2', tmp);
  191. if rc < 0 then
  192. begin
  193. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteElement');
  194. Exit;
  195. end;
  196. if tmp <> Nil then
  197. xmlFree(tmp);
  198. (* Close the element named HEADER. *)
  199. rc := xmlTextWriterEndElement(writer);
  200. if rc < 0 then
  201. begin
  202. printfn('testXmlwriterFilename: Error at xmlTextWriterEndElement');
  203. Exit;
  204. end;
  205. (* Start an element named "ENTRIES" as child of ORDER. *)
  206. rc := xmlTextWriterStartElement(writer, 'ENTRIES');
  207. if rc < 0 then
  208. begin
  209. printfn('testXmlwriterFilename: Error at xmlTextWriterStartElement');
  210. Exit;
  211. end;
  212. (* Start an element named "ENTRY" as child of ENTRIES. *)
  213. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  214. if rc < 0 then
  215. begin
  216. printfn('testXmlwriterFilename: Error at xmlTextWriterStartElement');
  217. Exit;
  218. end;
  219. (* Write an element named "ARTICLE" as child of ENTRY. *)
  220. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test>');
  221. if rc < 0 then
  222. begin
  223. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteElement');
  224. Exit;
  225. end;
  226. (* Write an element named "ENTRY_NO" as child of ENTRY. *)
  227. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [10]);
  228. if rc < 0 then
  229. begin
  230. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement');
  231. Exit;
  232. end;
  233. (* Close the element named ENTRY. *)
  234. rc := xmlTextWriterEndElement(writer);
  235. if rc < 0 then
  236. begin
  237. printfn('testXmlwriterFilename: Error at xmlTextWriterEndElement');
  238. Exit;
  239. end;
  240. (* Start an element named "ENTRY" as child of ENTRIES. *)
  241. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  242. if rc < 0 then
  243. begin
  244. printfn('testXmlwriterFilename: Error at xmlTextWriterStartElement');
  245. Exit;
  246. end;
  247. (* Write an element named "ARTICLE" as child of ENTRY. *)
  248. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test 2>');
  249. if rc < 0 then
  250. begin
  251. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteElement');
  252. Exit;
  253. end;
  254. (* Write an element named "ENTRY_NO" as child of ENTRY. *)
  255. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [20]);
  256. if rc < 0 then
  257. begin
  258. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteFormatElement');
  259. Exit;
  260. end;
  261. (* Close the element named ENTRY. *)
  262. rc := xmlTextWriterEndElement(writer);
  263. if rc < 0 then
  264. begin
  265. printfn('testXmlwriterFilename: Error at xmlTextWriterEndElement');
  266. Exit;
  267. end;
  268. (* Close the element named ENTRIES. *)
  269. rc := xmlTextWriterEndElement(writer);
  270. if (rc < 0) then
  271. begin
  272. printfn('testXmlwriterFilename: Error at xmlTextWriterEndElement');
  273. Exit;
  274. end;
  275. (* Start an element named "FOOTER" as child of ORDER. *)
  276. rc := xmlTextWriterStartElement(writer, 'FOOTER');
  277. if rc < 0 then
  278. begin
  279. printfn('testXmlwriterFilename: Error at xmlTextWriterStartElement');
  280. Exit;
  281. end;
  282. (* Write an element named "TEXT" as child of FOOTER. *)
  283. rc := xmlTextWriterWriteElement(writer, 'TEXT', 'This is a text.');
  284. if rc < 0 then
  285. begin
  286. printfn('testXmlwriterFilename: Error at xmlTextWriterWriteElement');
  287. Exit;
  288. end;
  289. (* Close the element named FOOTER. *)
  290. rc := xmlTextWriterEndElement(writer);
  291. if rc < 0 then
  292. begin
  293. printfn('testXmlwriterFilename: Error at xmlTextWriterEndElement');
  294. Exit;
  295. end;
  296. (* Here we could close the elements ORDER and EXAMPLE using the
  297. * function xmlTextWriterEndElement, but since we do not want to
  298. * write any other elements, we simply call xmlTextWriterEndDocument,
  299. * which will do all the work. *)
  300. rc := xmlTextWriterEndDocument(writer);
  301. if rc < 0 then
  302. begin
  303. printfn('testXmlwriterFilename: Error at xmlTextWriterEndDocument');
  304. Exit;
  305. end;
  306. xmlFreeTextWriter(writer);
  307. end;
  308. (**
  309. * testXmlwriterMemory:
  310. * @file: the output file
  311. *
  312. * test the xmlWriter interface when writing to memory
  313. *)
  314. procedure testXmlwriterMemory(const _file: PAnsiChar);
  315. var
  316. rc: cint;
  317. writer: xmlTextWriterPtr;
  318. buf: xmlBufferPtr;
  319. tmp: xmlCharPtr;
  320. fp: THandle;
  321. begin
  322. (* Create a new XML buffer, to which the XML document will be
  323. * written *)
  324. buf := xmlBufferCreate();
  325. if buf = Nil then
  326. begin
  327. printfn('testXmlwriterMemory: Error creating the xml buffer');
  328. Exit;
  329. end;
  330. (* Create a new XmlWriter for memory, with no compression.
  331. * Remark: there is no compression for this kind of xmlTextWriter *)
  332. writer := xmlNewTextWriterMemory(buf, 0);
  333. if writer = Nil then
  334. begin
  335. printfn('testXmlwriterMemory: Error creating the xml writer');
  336. Exit;
  337. end;
  338. (* Start the document with the xml default for the version,
  339. * encoding ISO 8859-1 and the default for the standalone
  340. * declaration. *)
  341. rc := xmlTextWriterStartDocument(writer, Nil, MY_ENCODING, Nil);
  342. if rc < 0 then
  343. begin
  344. printfn('testXmlwriterMemory: Error at xmlTextWriterStartDocument');
  345. Exit;
  346. end;
  347. (* Start an element named "EXAMPLE". Since thist is the first
  348. * element, this will be the root element of the document. *)
  349. rc := xmlTextWriterStartElement(writer, 'EXAMPLE');
  350. if rc < 0 then
  351. begin
  352. printfn('testXmlwriterMemory: Error at xmlTextWriterStartElement');
  353. Exit;
  354. end;
  355. (* Write a comment as child of EXAMPLE.
  356. * Please observe, that the input to the xmlTextWriter functions
  357. * HAS to be in UTF-8, even if the output XML is encoded
  358. * in iso-8859-1 *)
  359. tmp := ConvertInput('This is a comment with special chars: <'#$E4#$F6#$FC'>',
  360. MY_ENCODING);
  361. rc := xmlTextWriterWriteComment(writer, tmp);
  362. if rc < 0 then
  363. begin
  364. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteComment');
  365. Exit;
  366. end;
  367. if tmp <> Nil then
  368. xmlFree(tmp);
  369. (* Start an element named "ORDER" as child of EXAMPLE. *)
  370. rc := xmlTextWriterStartElement(writer, 'ORDER');
  371. if rc < 0 then
  372. begin
  373. printfn('testXmlwriterMemory: Error at xmlTextWriterStartElement');
  374. Exit;
  375. end;
  376. (* Add an attribute with name "version" and value "1.0" to ORDER. *)
  377. rc := xmlTextWriterWriteAttribute(writer, 'version', '1.0');
  378. if rc < 0 then
  379. begin
  380. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteAttribute');
  381. Exit;
  382. end;
  383. (* Add an attribute with name "xml:lang" and value "de" to ORDER. *)
  384. rc := xmlTextWriterWriteAttribute(writer, 'xml:lang', 'de');
  385. if rc < 0 then
  386. begin
  387. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteAttribute');
  388. Exit;
  389. end;
  390. (* Write a comment as child of ORDER *)
  391. tmp := ConvertInput('<'#$E4#$F6#$FC'>', MY_ENCODING);
  392. rc := xmlTextWriterWriteFormatComment(writer,
  393. 'This is another comment with special chars: %s', [tmp]);
  394. if rc < 0 then
  395. begin
  396. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteFormatComment');
  397. Exit;
  398. end;
  399. if tmp <> Nil then
  400. xmlFree(tmp);
  401. (* Start an element named "HEADER" as child of ORDER. *)
  402. rc := xmlTextWriterStartElement(writer, 'HEADER');
  403. if rc < 0 then
  404. begin
  405. printfn('testXmlwriterMemory: Error at xmlTextWriterStartElement\n');
  406. Exit;
  407. end;
  408. (* Write an element named "X_ORDER_ID" as child of HEADER. *)
  409. rc := xmlTextWriterWriteFormatElement(writer, 'X_ORDER_ID', '%010d', [53535]);
  410. if rc < 0 then
  411. begin
  412. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement');
  413. Exit;
  414. end;
  415. (* Write an element named "CUSTOMER_ID" as child of HEADER. *)
  416. rc := xmlTextWriterWriteFormatElement(writer, 'CUSTOMER_ID', '%d', [1010]);
  417. if rc < 0 then
  418. begin
  419. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement\n');
  420. Exit;
  421. end;
  422. (* Write an element named "NAME_1" as child of HEADER. *)
  423. tmp := ConvertInput('M'#$FC'ller', MY_ENCODING);
  424. rc := xmlTextWriterWriteElement(writer, 'NAME_1', tmp);
  425. if rc < 0 then
  426. begin
  427. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteElement');
  428. Exit;
  429. end;
  430. if tmp <> Nil then
  431. xmlFree(tmp);
  432. (* Write an element named "NAME_2" as child of HEADER. *)
  433. tmp := ConvertInput('J'#$F6'rg', MY_ENCODING);
  434. rc := xmlTextWriterWriteElement(writer, 'NAME_2', tmp);
  435. if rc < 0 then
  436. begin
  437. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteElement');
  438. Exit;
  439. end;
  440. if tmp <> Nil then
  441. xmlFree(tmp);
  442. (* Close the element named HEADER. *)
  443. rc := xmlTextWriterEndElement(writer);
  444. if rc < 0 then
  445. begin
  446. printfn('testXmlwriterMemory: Error at xmlTextWriterEndElement');
  447. Exit;
  448. end;
  449. (* Start an element named "ENTRIES" as child of ORDER. *)
  450. rc := xmlTextWriterStartElement(writer, 'ENTRIES');
  451. if rc < 0 then
  452. begin
  453. printfn('testXmlwriterMemory: Error at xmlTextWriterStartElement');
  454. Exit;
  455. end;
  456. (* Start an element named "ENTRY" as child of ENTRIES. *)
  457. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  458. if rc < 0 then
  459. begin
  460. printfn('testXmlwriterMemory: Error at xmlTextWriterStartElement');
  461. Exit;
  462. end;
  463. (* Write an element named "ARTICLE" as child of ENTRY. *)
  464. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test>');
  465. if rc < 0 then
  466. begin
  467. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteElement');
  468. Exit;
  469. end;
  470. (* Write an element named "ENTRY_NO" as child of ENTRY. *)
  471. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [10]);
  472. if rc < 0 then
  473. begin
  474. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement');
  475. Exit;
  476. end;
  477. (* Close the element named ENTRY. *)
  478. rc := xmlTextWriterEndElement(writer);
  479. if rc < 0 then
  480. begin
  481. printfn('testXmlwriterMemory: Error at xmlTextWriterEndElement');
  482. Exit;
  483. end;
  484. (* Start an element named "ENTRY" as child of ENTRIES. *)
  485. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  486. if rc < 0 then
  487. begin
  488. printfn('testXmlwriterMemory: Error at xmlTextWriterStartElement');
  489. Exit;
  490. end;
  491. (* Write an element named "ARTICLE" as child of ENTRY. *)
  492. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test 2>');
  493. if rc < 0 then
  494. begin
  495. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteElement\n');
  496. Exit;
  497. end;
  498. (* Write an element named "ENTRY_NO" as child of ENTRY. *)
  499. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [20]);
  500. if rc < 0 then
  501. begin
  502. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteFormatElement');
  503. Exit;
  504. end;
  505. (* Close the element named ENTRY. *)
  506. rc := xmlTextWriterEndElement(writer);
  507. if rc < 0 then
  508. begin
  509. printfn('testXmlwriterMemory: Error at xmlTextWriterEndElement');
  510. Exit;
  511. end;
  512. (* Close the element named ENTRIES. *)
  513. rc := xmlTextWriterEndElement(writer);
  514. if rc < 0 then
  515. begin
  516. printfn('testXmlwriterMemory: Error at xmlTextWriterEndElement');
  517. Exit;
  518. end;
  519. (* Start an element named "FOOTER" as child of ORDER. *)
  520. rc := xmlTextWriterStartElement(writer, 'FOOTER');
  521. if rc < 0 then
  522. begin
  523. printfn('testXmlwriterMemory: Error at xmlTextWriterStartElement');
  524. Exit;
  525. end;
  526. (* Write an element named "TEXT" as child of FOOTER. *)
  527. rc := xmlTextWriterWriteElement(writer, 'TEXT', 'This is a text.');
  528. if rc < 0 then
  529. begin
  530. printfn('testXmlwriterMemory: Error at xmlTextWriterWriteElement');
  531. Exit;
  532. end;
  533. (* Close the element named FOOTER. *)
  534. rc := xmlTextWriterEndElement(writer);
  535. if rc < 0 then
  536. begin
  537. printfn('testXmlwriterMemory: Error at xmlTextWriterEndElement');
  538. Exit;
  539. end;
  540. (* Here we could close the elements ORDER and EXAMPLE using the
  541. * function xmlTextWriterEndElement, but since we do not want to
  542. * write any other elements, we simply call xmlTextWriterEndDocument,
  543. * which will do all the work. *)
  544. rc := xmlTextWriterEndDocument(writer);
  545. if rc < 0 then
  546. begin
  547. printfn('testXmlwriterMemory: Error at xmlTextWriterEndDocument');
  548. Exit;
  549. end;
  550. xmlFreeTextWriter(writer);
  551. fp := FileCreate(_file);
  552. FileWrite(fp, buf^.content^, strlen(buf^.content));
  553. FileClose(fp);
  554. xmlBufferFree(buf);
  555. end;
  556. (**
  557. * testXmlwriterDoc:
  558. * @file: the output file
  559. *
  560. * test the xmlWriter interface when creating a new document
  561. *)
  562. procedure testXmlwriterDoc(const _file: PAnsiChar);
  563. var
  564. rc: cint;
  565. writer: xmlTextWriterPtr;
  566. tmp: xmlCharPtr;
  567. doc: xmlDocPtr;
  568. begin
  569. (* Create a new XmlWriter for DOM, with no compression. *)
  570. writer := xmlNewTextWriterDoc(doc, 0);
  571. if writer = Nil then
  572. begin
  573. printfn('testXmlwriterDoc: Error creating the xml writer');
  574. Exit;
  575. end;
  576. (* Start the document with the xml default for the version,
  577. * encoding ISO 8859-1 and the default for the standalone
  578. * declaration. *)
  579. rc := xmlTextWriterStartDocument(writer, Nil, MY_ENCODING, Nil);
  580. if rc < 0 then
  581. begin
  582. printfn('testXmlwriterDoc: Error at xmlTextWriterStartDocument');
  583. Exit;
  584. end;
  585. (* Start an element named 'EXAMPLE'. Since thist is the first
  586. * element, this will be the root element of the document. *)
  587. rc := xmlTextWriterStartElement(writer, 'EXAMPLE');
  588. if rc < 0 then
  589. begin
  590. printfn('testXmlwriterDoc: Error at xmlTextWriterStartElement');
  591. Exit;
  592. end;
  593. (* Write a comment as child of EXAMPLE.
  594. * Please observe, that the input to the xmlTextWriter functions
  595. * HAS to be in UTF-8, even if the output XML is encoded
  596. * in iso-8859-1 *)
  597. tmp := ConvertInput('This is a comment with special chars: <'#$E4#$F6#$FC'>',
  598. MY_ENCODING);
  599. rc := xmlTextWriterWriteComment(writer, tmp);
  600. if rc < 0 then
  601. begin
  602. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteComment');
  603. Exit;
  604. end;
  605. if tmp <> Nil then
  606. xmlFree(tmp);
  607. (* Start an element named 'ORDER' as child of EXAMPLE. *)
  608. rc := xmlTextWriterStartElement(writer, 'ORDER');
  609. if rc < 0 then
  610. begin
  611. printfn('testXmlwriterDoc: Error at xmlTextWriterStartElement');
  612. Exit;
  613. end;
  614. (* Add an attribute with name 'version' and value '1.0' to ORDER. *)
  615. rc := xmlTextWriterWriteAttribute(writer, 'version', '1.0');
  616. if rc < 0 then
  617. begin
  618. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteAttribute');
  619. Exit;
  620. end;
  621. (* Add an attribute with name 'xml:lang' and value 'de' to ORDER. *)
  622. rc := xmlTextWriterWriteAttribute(writer, 'xml:lang', 'de');
  623. if rc < 0 then
  624. begin
  625. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteAttribute');
  626. Exit;
  627. end;
  628. (* Write a comment as child of ORDER *)
  629. tmp := ConvertInput('<'#$E4#$F6#$FC'>', MY_ENCODING);
  630. rc := xmlTextWriterWriteFormatComment(writer,
  631. 'This is another comment with special chars: %s', [tmp]);
  632. if rc < 0 then
  633. begin
  634. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteFormatComment');
  635. Exit;
  636. end;
  637. if tmp <> Nil then
  638. xmlFree(tmp);
  639. (* Start an element named 'HEADER' as child of ORDER. *)
  640. rc := xmlTextWriterStartElement(writer, 'HEADER');
  641. if rc < 0 then
  642. begin
  643. printfn('testXmlwriterDoc: Error at xmlTextWriterStartElement');
  644. Exit;
  645. end;
  646. (* Write an element named 'X_ORDER_ID' as child of HEADER. *)
  647. rc := xmlTextWriterWriteFormatElement(writer, 'X_ORDER_ID', '%010d', [53535]);
  648. if rc < 0 then
  649. begin
  650. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement');
  651. Exit;
  652. end;
  653. (* Write an element named 'CUSTOMER_ID' as child of HEADER. *)
  654. rc := xmlTextWriterWriteFormatElement(writer, 'CUSTOMER_ID', '%d', [1010]);
  655. if rc < 0 then
  656. begin
  657. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement');
  658. Exit;
  659. end;
  660. (* Write an element named 'NAME_1' as child of HEADER. *)
  661. tmp := ConvertInput('M'#$FC'ller', MY_ENCODING);
  662. rc := xmlTextWriterWriteElement(writer, 'NAME_1', tmp);
  663. if rc < 0 then
  664. begin
  665. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteElement');
  666. Exit;
  667. end;
  668. if tmp <> Nil then
  669. xmlFree(tmp);
  670. (* Write an element named 'NAME_2' as child of HEADER. *)
  671. tmp := ConvertInput('J'#$F6'rg', MY_ENCODING);
  672. rc := xmlTextWriterWriteElement(writer, 'NAME_2', tmp);
  673. if rc < 0 then
  674. begin
  675. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteElement');
  676. Exit;
  677. end;
  678. if tmp <> Nil then
  679. xmlFree(tmp);
  680. (* Close the element named HEADER. *)
  681. rc := xmlTextWriterEndElement(writer);
  682. if rc < 0 then
  683. begin
  684. printfn('testXmlwriterDoc: Error at xmlTextWriterEndElement');
  685. Exit;
  686. end;
  687. (* Start an element named 'ENTRIES' as child of ORDER. *)
  688. rc := xmlTextWriterStartElement(writer, 'ENTRIES');
  689. if rc < 0 then
  690. begin
  691. printfn('testXmlwriterDoc: Error at xmlTextWriterStartElement');
  692. Exit;
  693. end;
  694. (* Start an element named 'ENTRY' as child of ENTRIES. *)
  695. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  696. if rc < 0 then
  697. begin
  698. printfn('testXmlwriterDoc: Error at xmlTextWriterStartElement');
  699. Exit;
  700. end;
  701. (* Write an element named 'ARTICLE' as child of ENTRY. *)
  702. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test>');
  703. if rc < 0 then
  704. begin
  705. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteElement');
  706. Exit;
  707. end;
  708. (* Write an element named 'ENTRY_NO' as child of ENTRY. *)
  709. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [10]);
  710. if rc < 0 then
  711. begin
  712. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement');
  713. Exit;
  714. end;
  715. (* Close the element named ENTRY. *)
  716. rc := xmlTextWriterEndElement(writer);
  717. if rc < 0 then
  718. begin
  719. printfn('testXmlwriterDoc: Error at xmlTextWriterEndElement');
  720. Exit;
  721. end;
  722. (* Start an element named 'ENTRY' as child of ENTRIES. *)
  723. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  724. if rc < 0 then
  725. begin
  726. printfn('testXmlwriterDoc: Error at xmlTextWriterStartElement');
  727. Exit;
  728. end;
  729. (* Write an element named 'ARTICLE' as child of ENTRY. *)
  730. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test 2>');
  731. if rc < 0 then
  732. begin
  733. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteElement');
  734. Exit;
  735. end;
  736. (* Write an element named 'ENTRY_NO' as child of ENTRY. *)
  737. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [20]);
  738. if rc < 0 then
  739. begin
  740. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteFormatElement');
  741. Exit;
  742. end;
  743. (* Close the element named ENTRY. *)
  744. rc := xmlTextWriterEndElement(writer);
  745. if rc < 0 then
  746. begin
  747. printfn('testXmlwriterDoc: Error at xmlTextWriterEndElement');
  748. Exit;
  749. end;
  750. (* Close the element named ENTRIES. *)
  751. rc := xmlTextWriterEndElement(writer);
  752. if rc < 0 then
  753. begin
  754. printfn('testXmlwriterDoc: Error at xmlTextWriterEndElement');
  755. Exit;
  756. end;
  757. (* Start an element named 'FOOTER' as child of ORDER. *)
  758. rc := xmlTextWriterStartElement(writer, 'FOOTER');
  759. if rc < 0 then
  760. begin
  761. printfn('testXmlwriterDoc: Error at xmlTextWriterStartElement');
  762. Exit;
  763. end;
  764. (* Write an element named 'TEXT' as child of FOOTER. *)
  765. rc := xmlTextWriterWriteElement(writer, 'TEXT', 'This is a text.');
  766. if rc < 0 then
  767. begin
  768. printfn('testXmlwriterDoc: Error at xmlTextWriterWriteElement');
  769. Exit;
  770. end;
  771. (* Close the element named FOOTER. *)
  772. rc := xmlTextWriterEndElement(writer);
  773. if rc < 0 then
  774. begin
  775. printfn('testXmlwriterDoc: Error at xmlTextWriterEndElement');
  776. Exit;
  777. end;
  778. (* Here we could close the elements ORDER and EXAMPLE using the
  779. * function xmlTextWriterEndElement, but since we do not want to
  780. * write any other elements, we simply call xmlTextWriterEndDocument,
  781. * which will do all the work. *)
  782. rc := xmlTextWriterEndDocument(writer);
  783. if rc < 0 then
  784. begin
  785. printfn('testXmlwriterDoc: Error at xmlTextWriterEndDocument');
  786. Exit;
  787. end;
  788. xmlFreeTextWriter(writer);
  789. xmlSaveFileEnc(_file, doc, MY_ENCODING);
  790. xmlFreeDoc(doc);
  791. end;
  792. (**
  793. * testXmlwriterTree:
  794. * @file: the output file
  795. *
  796. * test the xmlWriter interface when writing to a subtree
  797. *)
  798. procedure testXmlwriterTree(const _file: PAnsiChar);
  799. var
  800. rc: cint;
  801. writer: xmlTextWriterPtr;
  802. doc: xmlDocPtr;
  803. node: xmlNodePtr;
  804. tmp: xmlCharPtr;
  805. begin
  806. (* Create a new XML DOM tree, to which the XML document will be
  807. * written *)
  808. doc := xmlNewDoc(XML_DEFAULT_VERSION);
  809. if doc = Nil then
  810. begin
  811. printf('testXmlwriterTree: Error creating the xml document tree');
  812. Exit;
  813. end;
  814. (* Create a new XML node, to which the XML document will be
  815. * appended *)
  816. node := xmlNewDocNode(doc, Nil, 'EXAMPLE', Nil);
  817. if node = Nil then
  818. begin
  819. printf('testXmlwriterTree: Error creating the xml node');
  820. Exit;
  821. end;
  822. (* Make ELEMENT the root node of the tree *)
  823. xmlDocSetRootElement(doc, node);
  824. (* Create a new XmlWriter for DOM tree, with no compression. *)
  825. writer := xmlNewTextWriterTree(doc, node, 0);
  826. if writer = Nil then
  827. begin
  828. printf('testXmlwriterTree: Error creating the xml writer');
  829. Exit;
  830. end;
  831. (* Start the document with the xml default for the version,
  832. * encoding ISO 8859-1 and the default for the standalone
  833. * declaration. *)
  834. rc := xmlTextWriterStartDocument(writer, Nil, MY_ENCODING, Nil);
  835. if rc < 0 then
  836. begin
  837. printf('testXmlwriterTree: Error at xmlTextWriterStartDocument');
  838. Exit;
  839. end;
  840. (* Write a comment as child of EXAMPLE.
  841. * Please observe, that the input to the xmlTextWriter functions
  842. * HAS to be in UTF-8, even if the output XML is encoded
  843. * in iso-8859-1 *)
  844. tmp := ConvertInput('This is a comment with special chars: <'#$E4#$F6#$FC'>',
  845. MY_ENCODING);
  846. rc := xmlTextWriterWriteComment(writer, tmp);
  847. if rc < 0 then
  848. begin
  849. printf('testXmlwriterTree: Error at xmlTextWriterWriteComment');
  850. Exit;
  851. end;
  852. if tmp <> Nil then
  853. xmlFree(tmp);
  854. (* Start an element named 'ORDER' as child of EXAMPLE. *)
  855. rc := xmlTextWriterStartElement(writer, 'ORDER');
  856. if rc < 0 then
  857. begin
  858. printf('testXmlwriterTree: Error at xmlTextWriterStartElement');
  859. Exit;
  860. end;
  861. (* Add an attribute with name 'version' and value '1.0' to ORDER. *)
  862. rc := xmlTextWriterWriteAttribute(writer, 'version', '1.0');
  863. if rc < 0 then
  864. begin
  865. printf('testXmlwriterTree: Error at xmlTextWriterWriteAttribute');
  866. Exit;
  867. end;
  868. (* Add an attribute with name 'xml:lang' and value 'de' to ORDER. *)
  869. rc := xmlTextWriterWriteAttribute(writer, 'xml:lang', 'de');
  870. if rc < 0 then
  871. begin
  872. printf('testXmlwriterTree: Error at xmlTextWriterWriteAttribute');
  873. Exit;
  874. end;
  875. (* Write a comment as child of ORDER *)
  876. tmp := ConvertInput('<'#$E4#$F6#$FC'>', MY_ENCODING);
  877. rc := xmlTextWriterWriteFormatComment(writer,
  878. 'This is another comment with special chars: %s', [tmp]);
  879. if rc < 0 then
  880. begin
  881. printf('testXmlwriterTree: Error at xmlTextWriterWriteFormatComment');
  882. Exit;
  883. end;
  884. if tmp <> Nil then
  885. xmlFree(tmp);
  886. (* Start an element named 'HEADER' as child of ORDER. *)
  887. rc := xmlTextWriterStartElement(writer, 'HEADER');
  888. if rc < 0 then
  889. begin
  890. printf('testXmlwriterTree: Error at xmlTextWriterStartElement');
  891. Exit;
  892. end;
  893. (* Write an element named 'X_ORDER_ID' as child of HEADER. *)
  894. rc := xmlTextWriterWriteFormatElement(writer, 'X_ORDER_ID', '%010d', [53535]);
  895. if rc < 0 then
  896. begin
  897. printf('testXmlwriterTree: Error at xmlTextWriterWriteFormatElement');
  898. Exit;
  899. end;
  900. (* Write an element named 'CUSTOMER_ID' as child of HEADER. *)
  901. rc := xmlTextWriterWriteFormatElement(writer, 'CUSTOMER_ID', '%d', [1010]);
  902. if rc < 0 then
  903. begin
  904. printf('testXmlwriterTree: Error at xmlTextWriterWriteFormatElement');
  905. Exit;
  906. end;
  907. (* Write an element named 'NAME_1' as child of HEADER. *)
  908. tmp := ConvertInput('M'#$FC'ller', MY_ENCODING);
  909. rc := xmlTextWriterWriteElement(writer, 'NAME_1', tmp);
  910. if rc < 0 then
  911. begin
  912. printf('testXmlwriterTree: Error at xmlTextWriterWriteElement');
  913. Exit;
  914. end;
  915. if tmp <> Nil then
  916. xmlFree(tmp);
  917. (* Write an element named 'NAME_2' as child of HEADER. *)
  918. tmp := ConvertInput('J'#$F6'rg', MY_ENCODING);
  919. rc := xmlTextWriterWriteElement(writer, 'NAME_2', tmp);
  920. if rc < 0 then
  921. begin
  922. printf('testXmlwriterTree: Error at xmlTextWriterWriteElement');
  923. Exit;
  924. end;
  925. if tmp <> Nil then
  926. xmlFree(tmp);
  927. (* Close the element named HEADER. *)
  928. rc := xmlTextWriterEndElement(writer);
  929. if rc < 0 then
  930. begin
  931. printf('testXmlwriterTree: Error at xmlTextWriterEndElement');
  932. Exit;
  933. end;
  934. (* Start an element named 'ENTRIES' as child of ORDER. *)
  935. rc := xmlTextWriterStartElement(writer, 'ENTRIES');
  936. if rc < 0 then
  937. begin
  938. printf('testXmlwriterTree: Error at xmlTextWriterStartElement');
  939. Exit;
  940. end;
  941. (* Start an element named 'ENTRY' as child of ENTRIES. *)
  942. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  943. if rc < 0 then
  944. begin
  945. printf('testXmlwriterTree: Error at xmlTextWriterStartElement');
  946. Exit;
  947. end;
  948. (* Write an element named 'ARTICLE' as child of ENTRY. *)
  949. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test>');
  950. if rc < 0 then
  951. begin
  952. printf('testXmlwriterTree: Error at xmlTextWriterWriteElement');
  953. Exit;
  954. end;
  955. (* Write an element named 'ENTRY_NO' as child of ENTRY. *)
  956. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [10]);
  957. if rc < 0 then
  958. begin
  959. printf('testXmlwriterTree: Error at xmlTextWriterWriteFormatElement');
  960. Exit;
  961. end;
  962. (* Close the element named ENTRY. *)
  963. rc := xmlTextWriterEndElement(writer);
  964. if rc < 0 then
  965. begin
  966. printf('testXmlwriterTree: Error at xmlTextWriterEndElement');
  967. Exit;
  968. end;
  969. (* Start an element named 'ENTRY' as child of ENTRIES. *)
  970. rc := xmlTextWriterStartElement(writer, 'ENTRY');
  971. if rc < 0 then
  972. begin
  973. printf('testXmlwriterTree: Error at xmlTextWriterStartElement');
  974. Exit;
  975. end;
  976. (* Write an element named 'ARTICLE' as child of ENTRY. *)
  977. rc := xmlTextWriterWriteElement(writer, 'ARTICLE', '<Test 2>');
  978. if rc < 0 then
  979. begin
  980. printf('testXmlwriterTree: Error at xmlTextWriterWriteElement');
  981. Exit;
  982. end;
  983. (* Write an element named 'ENTRY_NO' as child of ENTRY. *)
  984. rc := xmlTextWriterWriteFormatElement(writer, 'ENTRY_NO', '%d', [20]);
  985. if rc < 0 then
  986. begin
  987. printf('testXmlwriterTree: Error at xmlTextWriterWriteFormatElement');
  988. Exit;
  989. end;
  990. (* Close the element named ENTRY. *)
  991. rc := xmlTextWriterEndElement(writer);
  992. if rc < 0 then
  993. begin
  994. printf('testXmlwriterTree: Error at xmlTextWriterEndElement');
  995. Exit;
  996. end;
  997. (* Close the element named ENTRIES. *)
  998. rc := xmlTextWriterEndElement(writer);
  999. if rc < 0 then
  1000. begin
  1001. printf('testXmlwriterTree: Error at xmlTextWriterEndElement');
  1002. Exit;
  1003. end;
  1004. (* Start an element named 'FOOTER' as child of ORDER. *)
  1005. rc := xmlTextWriterStartElement(writer, 'FOOTER');
  1006. if rc < 0 then
  1007. begin
  1008. printf('testXmlwriterTree: Error at xmlTextWriterStartElement');
  1009. Exit;
  1010. end;
  1011. (* Write an element named 'TEXT' as child of FOOTER. *)
  1012. rc := xmlTextWriterWriteElement(writer, 'TEXT', 'This is a text.');
  1013. if rc < 0 then
  1014. begin
  1015. printf('testXmlwriterTree: Error at xmlTextWriterWriteElement');
  1016. Exit;
  1017. end;
  1018. (* Close the element named FOOTER. *)
  1019. rc := xmlTextWriterEndElement(writer);
  1020. if rc < 0 then
  1021. begin
  1022. printf('testXmlwriterTree: Error at xmlTextWriterEndElement');
  1023. Exit;
  1024. end;
  1025. (* Here we could close the elements ORDER and EXAMPLE using the
  1026. * function xmlTextWriterEndElement, but since we do not want to
  1027. * write any other elements, we simply call xmlTextWriterEndDocument,
  1028. * which will do all the work. *)
  1029. rc := xmlTextWriterEndDocument(writer);
  1030. if rc < 0 then
  1031. begin
  1032. printf('testXmlwriterTree: Error at xmlTextWriterEndDocument');
  1033. Exit;
  1034. end;
  1035. xmlFreeTextWriter(writer);
  1036. xmlSaveFileEnc(_file, doc, MY_ENCODING);
  1037. xmlFreeDoc(doc);
  1038. end;
  1039. begin
  1040. (*
  1041. * this initialize the library and check potential ABI mismatches
  1042. * between the version it was compiled for and the actual shared
  1043. * library used.
  1044. *)
  1045. LIBXML_TEST_VERSION;
  1046. (* first, the file version *)
  1047. testXmlwriterFilename('writer1.tmp');
  1048. (* next, the memory version *)
  1049. testXmlwriterMemory('writer2.tmp');
  1050. (* next, the DOM version *)
  1051. testXmlwriterDoc('writer3.tmp');
  1052. (* next, the tree version *)
  1053. testXmlwriterTree('writer4.tmp');
  1054. (*
  1055. * Cleanup function for the XML library.
  1056. *)
  1057. xmlCleanupParser();
  1058. (*
  1059. * this is to debug memory for regression tests
  1060. *)
  1061. xmlMemoryDump();
  1062. end.