parse4.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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 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. #include <stdio.h>
  13. #include <libxml/parser.h>
  14. #include <libxml/tree.h>
  15. #ifdef LIBXML_PUSH_ENABLED
  16. static FILE *desc;
  17. /**
  18. * readPacket:
  19. * @mem: array to store the packet
  20. * @size: the packet size
  21. *
  22. * read at most @size bytes from the document and store it in @mem
  23. *
  24. * Returns the number of bytes read
  25. */
  26. static int
  27. readPacket(char *mem, int size) {
  28. int res;
  29. res = fread(mem, 1, size, desc);
  30. return(res);
  31. }
  32. /**
  33. * example4Func:
  34. * @filename: a filename or an URL
  35. *
  36. * Parse the resource and free the resulting tree
  37. */
  38. static void
  39. example4Func(const char *filename) {
  40. xmlParserCtxtPtr ctxt;
  41. char chars[4];
  42. xmlDocPtr doc; /* the resulting document tree */
  43. int res;
  44. /*
  45. * Read a few first byte to check the input used for the
  46. * encoding detection at the parser level.
  47. */
  48. res = readPacket(chars, 4);
  49. if (res <= 0) {
  50. fprintf(stderr, "Failed to parse %s\n", filename);
  51. return;
  52. }
  53. /*
  54. * Create a progressive parsing context, the 2 first arguments
  55. * are not used since we want to build a tree and not use a SAX
  56. * parsing interface. We also pass the first bytes of the document
  57. * to allow encoding detection when creating the parser but this
  58. * is optional.
  59. */
  60. ctxt = xmlCreatePushParserCtxt(NULL, NULL,
  61. chars, res, filename);
  62. if (ctxt == NULL) {
  63. fprintf(stderr, "Failed to create parser context !\n");
  64. return;
  65. }
  66. /*
  67. * loop on the input getting the document data, of course 4 bytes
  68. * at a time is not realistic but allows to verify testing on small
  69. * documents.
  70. */
  71. while ((res = readPacket(chars, 4)) > 0) {
  72. xmlParseChunk(ctxt, chars, res, 0);
  73. }
  74. /*
  75. * there is no more input, indicate the parsing is finished.
  76. */
  77. xmlParseChunk(ctxt, chars, 0, 1);
  78. /*
  79. * collect the document back and if it was wellformed
  80. * and destroy the parser context.
  81. */
  82. doc = ctxt->myDoc;
  83. res = ctxt->wellFormed;
  84. xmlFreeParserCtxt(ctxt);
  85. if (!res) {
  86. fprintf(stderr, "Failed to parse %s\n", filename);
  87. }
  88. /*
  89. * since we don't use the document, destroy it now.
  90. */
  91. xmlFreeDoc(doc);
  92. }
  93. int main(int argc, char **argv) {
  94. if (argc != 2)
  95. return(1);
  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. * simulate a progressive parsing using the input file.
  104. */
  105. desc = fopen(argv[1], "rb");
  106. if (desc != NULL) {
  107. example4Func(argv[1]);
  108. fclose(desc);
  109. } else {
  110. fprintf(stderr, "Failed to parse %s\n", argv[1]);
  111. }
  112. /*
  113. * Cleanup function for the XML library.
  114. */
  115. xmlCleanupParser();
  116. /*
  117. * this is to debug memory for regression tests
  118. */
  119. xmlMemoryDump();
  120. return(0);
  121. }
  122. #else /* ! LIBXML_PUSH_ENABLED */
  123. int main(int argc, char **argv) {
  124. fprintf(stderr, "Library not compiled with push parser support\n");
  125. return(1);
  126. }
  127. #endif