parse4.pas 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. (**
  2. * section: Parsing
  3. * synopsis: Parse an XML document chunk by chunk to a tree and free it
  4. * purpose: Demonstrate the use of xmlCreatePushParserCtxt() and
  5. * xmlParseChunk() to read an XML file progressively
  6. * into a tree and xmlFreeDoc() to free the resulting tree
  7. * usage: parse4 test3.xml
  8. * test: parse4 test3.xml
  9. * author: Daniel Veillard
  10. * copy: see Copyright for the status of this software.
  11. *)
  12. program parse4;
  13. {$mode objfpc}
  14. uses
  15. xml2,
  16. exutils,
  17. ctypes;
  18. procedure processDoc(readerPtr: xmlTextReaderPtr);
  19. var
  20. ret: cint;
  21. docPtr: xmlDocPtr;
  22. URL: PAnsiChar;
  23. begin
  24. ret := xmlTextReaderRead(readerPtr);
  25. while ret = 1 do
  26. ret := xmlTextReaderRead(readerPtr);
  27. (*
  28. * One can obtain the document pointer to get interesting
  29. * information about the document like the URL, but one must also
  30. * be sure to clean it up at the end (see below).
  31. *)
  32. docPtr := xmlTextReaderCurrentDoc(readerPtr);
  33. if docPtr = Nil then
  34. begin
  35. printfn('failed to obtain document');
  36. Exit;
  37. end;
  38. URL := docPtr^.URL;
  39. if URL = Nil then
  40. printfn('Failed to obtain URL');
  41. if ret <> 0 then
  42. begin
  43. printfn('%s: Failed to parse', [URL]);
  44. Exit;
  45. end;
  46. printfn('%s: Processed ok', [URL]);
  47. end;
  48. var
  49. readerPtr: xmlTextReaderPtr;
  50. i: cint;
  51. docPtr: xmlDocPtr;
  52. begin
  53. if ParamCount < 1 then
  54. Halt(1);
  55. (*
  56. * this initialises the library and check potential ABI mismatches
  57. * between the version it was compiled for and the actual shared
  58. * library used.
  59. *)
  60. LIBXML_TEST_VERSION;
  61. (*
  62. * Create a new reader for the first file and process the
  63. * document.
  64. *)
  65. readerPtr := xmlReaderForFile(PAnsiChar(ParamStr(1)), Nil, 0);
  66. if readerPtr = Nil then
  67. begin
  68. printfn('%s: failed to create reader', [ParamStr(1)]);
  69. Halt(1);
  70. end;
  71. processDoc(readerPtr);
  72. (*
  73. * The reader can be reused for subsequent files.
  74. *)
  75. for i := 2 to ParamCount do
  76. begin
  77. xmlReaderNewFile(readerPtr, PAnsiChar(ParamStr(i)), Nil, 0);
  78. if readerPtr = Nil then
  79. begin
  80. printfn('%s: failed to create reader', [ParamStr(i)]);
  81. Halt(1);
  82. end;
  83. processDoc(readerPtr);
  84. end;
  85. (*
  86. * Since we've called xmlTextReaderCurrentDoc, we now have to
  87. * clean up after ourselves. We only have to do this the last
  88. * time, because xmlReaderNewFile calls xmlCtxtReset which takes
  89. * care of it.
  90. *)
  91. docPtr := xmlTextReaderCurrentDoc(readerPtr);
  92. if docPtr <> Nil then
  93. xmlFreeDoc(docPtr);
  94. (*
  95. * Clean up the reader.
  96. *)
  97. xmlFreeTextReader(readerPtr);
  98. (*
  99. * Cleanup function for the XML library.
  100. *)
  101. xmlCleanupParser();
  102. (*
  103. * this is to debug memory for regression tests
  104. *)
  105. xmlMemoryDump();
  106. end.