io1.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. #include <stdio.h>
  14. #include <string.h>
  15. #include <libxml/parser.h>
  16. #include <libxml/tree.h>
  17. #include <libxml/xinclude.h>
  18. #include <libxml/xmlIO.h>
  19. #ifdef LIBXML_XINCLUDE_ENABLED
  20. static const char *result = "<list><people>a</people><people>b</people></list>";
  21. static const char *cur = NULL;
  22. static int rlen;
  23. /**
  24. * sqlMatch:
  25. * @URI: an URI to test
  26. *
  27. * Check for an sql: query
  28. *
  29. * Returns 1 if yes and 0 if another Input module should be used
  30. */
  31. static int
  32. sqlMatch(const char * URI) {
  33. if ((URI != NULL) && (!strncmp(URI, "sql:", 4)))
  34. return(1);
  35. return(0);
  36. }
  37. /**
  38. * sqlOpen:
  39. * @URI: an URI to test
  40. *
  41. * Return a pointer to the sql: query handler, in this example simply
  42. * the current pointer...
  43. *
  44. * Returns an Input context or NULL in case or error
  45. */
  46. static void *
  47. sqlOpen(const char * URI) {
  48. if ((URI == NULL) || (strncmp(URI, "sql:", 4)))
  49. return(NULL);
  50. cur = result;
  51. rlen = strlen(result);
  52. return((void *) cur);
  53. }
  54. /**
  55. * sqlClose:
  56. * @context: the read context
  57. *
  58. * Close the sql: query handler
  59. *
  60. * Returns 0 or -1 in case of error
  61. */
  62. static int
  63. sqlClose(void * context) {
  64. if (context == NULL) return(-1);
  65. cur = NULL;
  66. rlen = 0;
  67. return(0);
  68. }
  69. /**
  70. * sqlRead:
  71. * @context: the read context
  72. * @buffer: where to store data
  73. * @len: number of bytes to read
  74. *
  75. * Implement an sql: query read.
  76. *
  77. * Returns the number of bytes read or -1 in case of error
  78. */
  79. static int
  80. sqlRead(void * context, char * buffer, int len) {
  81. const char *ptr = (const char *) context;
  82. if ((context == NULL) || (buffer == NULL) || (len < 0))
  83. return(-1);
  84. if (len > rlen) len = rlen;
  85. memcpy(buffer, ptr, len);
  86. rlen -= len;
  87. return(len);
  88. }
  89. const char *include = "<?xml version='1.0'?>\n\
  90. <document xmlns:xi=\"http://www.w3.org/2003/XInclude\">\n\
  91. <p>List of people:</p>\n\
  92. <xi:include href=\"sql:select_name_from_people\"/>\n\
  93. </document>\n";
  94. int main(void) {
  95. xmlDocPtr doc;
  96. /*
  97. * this initialize the library and check potential ABI mismatches
  98. * between the version it was compiled for and the actual shared
  99. * library used.
  100. */
  101. LIBXML_TEST_VERSION
  102. /*
  103. * register the new I/O handlers
  104. */
  105. if (xmlRegisterInputCallbacks(sqlMatch, sqlOpen, sqlRead, sqlClose) < 0) {
  106. fprintf(stderr, "failed to register SQL handler\n");
  107. exit(1);
  108. }
  109. /*
  110. * parse include into a document
  111. */
  112. doc = xmlReadMemory(include, strlen(include), "include.xml", NULL, 0);
  113. if (doc == NULL) {
  114. fprintf(stderr, "failed to parse the including file\n");
  115. exit(1);
  116. }
  117. /*
  118. * apply the XInclude process, this should trigger the I/O just
  119. * registered.
  120. */
  121. if (xmlXIncludeProcess(doc) <= 0) {
  122. fprintf(stderr, "XInclude processing failed\n");
  123. exit(1);
  124. }
  125. #ifdef LIBXML_OUTPUT_ENABLED
  126. /*
  127. * save the output for checking to stdout
  128. */
  129. xmlDocDump(stdout, doc);
  130. #endif
  131. /*
  132. * Free the document
  133. */
  134. xmlFreeDoc(doc);
  135. /*
  136. * Cleanup function for the XML library.
  137. */
  138. xmlCleanupParser();
  139. /*
  140. * this is to debug memory for regression tests
  141. */
  142. xmlMemoryDump();
  143. return(0);
  144. }
  145. #else
  146. int main(void) {
  147. fprintf(stderr, "XInclude support not compiled in\n");
  148. exit(1);
  149. }
  150. #endif