xmlstream.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 /* <DESC>
00023  * Stream-parse a document using the streaming Expat parser.
00024  * </DESC>
00025  */
00026 /* Written by David Strauss
00027  *
00028  * Expat => http://www.libexpat.org/
00029  *
00030  * gcc -Wall -I/usr/local/include xmlstream.c -lcurl -lexpat -o xmlstream
00031  *
00032  */
00033 
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <assert.h>
00038 
00039 #include <expat.h>
00040 #include <curl/curl.h>
00041 
00042 struct MemoryStruct {
00043   char *memory;
00044   size_t size;
00045 };
00046 
00047 struct ParserStruct {
00048   int ok;
00049   size_t tags;
00050   size_t depth;
00051   struct MemoryStruct characters;
00052 };
00053 
00054 static void startElement(void *userData, const XML_Char *name,
00055                          const XML_Char **atts)
00056 {
00057   struct ParserStruct *state = (struct ParserStruct *) userData;
00058   state->tags++;
00059   state->depth++;
00060 
00061   /* Get a clean slate for reading in character data. */
00062   free(state->characters.memory);
00063   state->characters.memory = NULL;
00064   state->characters.size = 0;
00065 }
00066 
00067 static void characterDataHandler(void *userData, const XML_Char *s, int len)
00068 {
00069   struct ParserStruct *state = (struct ParserStruct *) userData;
00070   struct MemoryStruct *mem = &state->characters;
00071 
00072   mem->memory = realloc(mem->memory, mem->size + len + 1);
00073   if(mem->memory == NULL) {
00074     /* Out of memory. */
00075     fprintf(stderr, "Not enough memory (realloc returned NULL).\n");
00076     state->ok = 0;
00077     return;
00078   }
00079 
00080   memcpy(&(mem->memory[mem->size]), s, len);
00081   mem->size += len;
00082   mem->memory[mem->size] = 0;
00083 }
00084 
00085 static void endElement(void *userData, const XML_Char *name)
00086 {
00087   struct ParserStruct *state = (struct ParserStruct *) userData;
00088   state->depth--;
00089 
00090   printf("%5lu   %10lu   %s\n", state->depth, state->characters.size, name);
00091 }
00092 
00093 static size_t parseStreamCallback(void *contents, size_t length, size_t nmemb,
00094                                   void *userp)
00095 {
00096   XML_Parser parser = (XML_Parser) userp;
00097   size_t real_size = length * nmemb;
00098   struct ParserStruct *state = (struct ParserStruct *) XML_GetUserData(parser);
00099 
00100   /* Only parse if we're not already in a failure state. */
00101   if(state->ok && XML_Parse(parser, contents, real_size, 0) == 0) {
00102     int error_code = XML_GetErrorCode(parser);
00103     fprintf(stderr, "Parsing response buffer of length %lu failed"
00104             " with error code %d (%s).\n",
00105             real_size, error_code, XML_ErrorString(error_code));
00106     state->ok = 0;
00107   }
00108 
00109   return real_size;
00110 }
00111 
00112 int main(void)
00113 {
00114   CURL *curl_handle;
00115   CURLcode res;
00116   XML_Parser parser;
00117   struct ParserStruct state;
00118 
00119   /* Initialize the state structure for parsing. */
00120   memset(&state, 0, sizeof(struct ParserStruct));
00121   state.ok = 1;
00122 
00123   /* Initialize a namespace-aware parser. */
00124   parser = XML_ParserCreateNS(NULL, '\0');
00125   XML_SetUserData(parser, &state);
00126   XML_SetElementHandler(parser, startElement, endElement);
00127   XML_SetCharacterDataHandler(parser, characterDataHandler);
00128 
00129   /* Initialize a libcurl handle. */
00130   curl_global_init(CURL_GLOBAL_ALL ^ CURL_GLOBAL_SSL);
00131   curl_handle = curl_easy_init();
00132   curl_easy_setopt(curl_handle, CURLOPT_URL,
00133                    "http://www.w3schools.com/xml/simple.xml");
00134   curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, parseStreamCallback);
00135   curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)parser);
00136 
00137   printf("Depth   Characters   Closing Tag\n");
00138 
00139   /* Perform the request and any follow-up parsing. */
00140   res = curl_easy_perform(curl_handle);
00141   if(res != CURLE_OK) {
00142     fprintf(stderr, "curl_easy_perform() failed: %s\n",
00143             curl_easy_strerror(res));
00144   }
00145   else if(state.ok) {
00146     /* Expat requires one final call to finalize parsing. */
00147     if(XML_Parse(parser, NULL, 0, 1) == 0) {
00148       int error_code = XML_GetErrorCode(parser);
00149       fprintf(stderr, "Finalizing parsing failed with error code %d (%s).\n",
00150               error_code, XML_ErrorString(error_code));
00151     }
00152     else {
00153       printf("                     --------------\n");
00154       printf("                     %lu tags total\n", state.tags);
00155     }
00156   }
00157 
00158   /* Clean up. */
00159   free(state.characters.memory);
00160   XML_ParserFree(parser);
00161   curl_easy_cleanup(curl_handle);
00162   curl_global_cleanup();
00163 
00164   return 0;
00165 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:07