io1.pas 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. (**
  2. * section: InputOutput
  3. * synopsis: Example of custom Input/Output
  4. * purpose: Demonstrate the use of xmlRegisterInputCallbacks
  5. * to build a custom I/O layer, this is used in an
  6. * XInclude method context to show how dynamic document can
  7. * be built in a clean way.
  8. * usage: io1
  9. * test: io1 > io1.tmp ; diff io1.tmp io1.res ; rm -f io1.tmp
  10. * author: Daniel Veillard
  11. * copy: see Copyright for the status of this software.
  12. *)
  13. program io1;
  14. {$mode objfpc}
  15. uses
  16. ctypes,
  17. xml2,
  18. exutils,
  19. SysUtils;
  20. const
  21. include: pchar =
  22. '<?xml version=''1.0''?>'#10+
  23. '<document xmlns:xi="http://www.w3.org/2003/XInclude">'#10+
  24. '<p>List of people:</p>'#10+
  25. '<xi:include href="sql:select_name_from_people"/>'#10+
  26. '</document>'#10;
  27. var
  28. res: pchar = '<list><people>a</people><people>b</people></list>';
  29. cur: pchar = nil;
  30. rlen: cint = 0;
  31. (**
  32. * sqlMatch:
  33. * @URI: an URI to test
  34. *
  35. * Check for an sql: query
  36. *
  37. * Returns 1 if yes and 0 if another Input module should be used
  38. *)
  39. function sqlMatch(URI: pchar): cint; cdecl;
  40. begin
  41. if assigned(URI) and (strlcomp(URI, 'sql:', 4) = 0) then
  42. result := 1
  43. else
  44. result := 0;
  45. end;
  46. (**
  47. * sqlOpen:
  48. * @URI: an URI to test
  49. *
  50. * Return a pointer to the sql: query handler, in this example simply
  51. * the current pointer...
  52. *
  53. * Returns an Input context or NULL in case or error
  54. *)
  55. function sqlOpen(URI: pchar): pointer; cdecl;
  56. begin
  57. if not assigned(URI) or (strlcomp(URI, 'sql:', 4) <> 0) then
  58. exit(nil);
  59. cur := res;
  60. rlen := strlen(res);
  61. result := pointer(cur);
  62. end;
  63. (**
  64. * sqlClose:
  65. * @context: the read context
  66. *
  67. * Close the sql: query handler
  68. *
  69. * Returns 0 or -1 in case of error
  70. *)
  71. function sqlClose(context: pointer): cint; cdecl;
  72. begin
  73. if not assigned(context) then
  74. exit(-1);
  75. cur := nil;
  76. rlen := 0;
  77. result := 0;
  78. end;
  79. (**
  80. * sqlRead:
  81. * @context: the read context
  82. * @buffer: where to store data
  83. * @len: number of bytes to read
  84. *
  85. * Implement an sql: query read.
  86. *
  87. * Returns the number of bytes read or -1 in case of error
  88. *)
  89. function sqlRead(context: pointer; buffer: pchar; len: cint): cint; cdecl;
  90. var
  91. ptr: pchar;
  92. begin
  93. if not assigned(context) or not assigned(buffer) or (len < 0) then
  94. exit(-1);
  95. ptr := context;
  96. if len > rlen then
  97. len := rlen;
  98. move(ptr^, buffer^, len);
  99. rlen := rlen - len;
  100. result := len;
  101. end;
  102. var
  103. doc: xmlDocPtr;
  104. begin
  105. (*
  106. * this initialize the library and check potential ABI mismatches
  107. * between the version it was compiled for and the actual shared
  108. * library used.
  109. *)
  110. LIBXML_TEST_VERSION;
  111. (*
  112. * register the new I/O handlers
  113. *)
  114. if xmlRegisterInputCallbacks(@sqlMatch, @sqlOpen, @sqlRead, @sqlClose) < 0 then
  115. begin
  116. printfn('failed to register SQL handler');
  117. halt(1);
  118. end;
  119. (*
  120. * parse include into a document
  121. *)
  122. doc := xmlReadMemory(include, strlen(include), 'include.xml', nil, 0);
  123. if doc = nil then
  124. begin
  125. printfn('failed to parse the including file');
  126. halt(1);
  127. end;
  128. (*
  129. * apply the XInclude process, this should trigger the I/O just
  130. * registered.
  131. *)
  132. if xmlXIncludeProcess(doc) <= 0 then
  133. begin
  134. printfn('XInclude processing failed');
  135. halt(1);
  136. end;
  137. (*
  138. * save the output for checking to stdout
  139. *)
  140. // xmlDocDump(stdout, doc);
  141. (*
  142. * Free the document
  143. *)
  144. //xmlDumpDoc(doc);
  145. docdump(doc);
  146. (*
  147. * Cleanup function for the XML library.
  148. *)
  149. xmlCleanupParser();
  150. end.