00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <libxml/parser.h>
00016 #include <libxml/xpath.h>
00017 #include <libxml/xpathInternals.h>
00018 #include "sasa_c_xml.h"
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 #define MAX_OPEN_DOCUMENTS    100
00056 xmlDocPtr open_doc[MAX_OPEN_DOCUMENTS];
00057 
00058 int nb_open_doc = -1;
00059 
00060 int
00061 sasaOpenXml(const char *filename)
00062 {
00063     xmlDocPtr doc;
00064     int num_doc;
00065         int i;
00066     
00067     
00068     if (nb_open_doc == -1)
00069     {
00070         for (i = 0; i < MAX_OPEN_DOCUMENTS; i += 1)
00071             open_doc[i] = NULL;
00072         nb_open_doc = 0;
00073     }
00074 
00075     if (nb_open_doc == MAX_OPEN_DOCUMENTS)
00076     {
00077         fprintf(stderr, "%s:%d: number of open XML documents is too large.\n", 
00078                   __FILE__, __LINE__);
00079         return -1;
00080     }
00081     else
00082     {
00083         
00084         doc = xmlParseFile(filename);
00085         if(doc == (xmlDocPtr) NULL)
00086         {
00087             fprintf(stderr, "%s:%d: document not parsed successfully.\n", 
00088                     __FILE__, __LINE__);
00089             return -1;
00090         }
00091         else
00092         {
00093             
00094             for (num_doc = 0; open_doc[num_doc] != NULL; num_doc += 1)
00095                 ;
00096             
00097             open_doc[num_doc] = doc;
00098             nb_open_doc += 1;
00099             
00100             return num_doc;
00101         }
00102     }
00103 }  
00104 
00105 
00106 int
00107 sasaCloseXml(int num_doc)
00108 {
00109     xmlDocPtr doc;
00110     
00111     
00112     doc = open_doc[num_doc];
00113     xmlFreeDoc(doc);
00114     
00115     
00116     open_doc[num_doc] = NULL;
00117     nb_open_doc -= 1;
00118     
00119     return EXIT_SUCCESS;
00120     
00121 }  
00122 
00123 
00124 
00125 
00126 
00127 int
00128 getXmlNodeCount(int num_doc, const char *nodeName, int *nodeNumber)
00129 {
00130     xmlDocPtr doc;
00131     size_t length = 0;
00132     char *xpathBase = "count (//", *xpath = NULL;
00133     char *nodeNameNs = NULL;
00134     xmlNodePtr  root = NULL;
00135 
00136     xmlXPathContextPtr context    = NULL;
00137     xmlChar            *xpathExpr = NULL;
00138     xmlXPathObjectPtr  result     = NULL;
00139     
00140     doc = open_doc[num_doc];
00141     root = xmlDocGetRootElement(doc);
00142     
00143     if(root == NULL)
00144     {
00145         printf("XML File Error : No root element !\n");
00146         *nodeNumber = 0;
00147         
00148         return EXIT_FAILURE;
00149     }
00150 
00151     if(nodeName == NULL || (*nodeName) == '\0')
00152     {
00153         printf("No node name to count !\n");
00154         *nodeNumber = 0;
00155         
00156         return EXIT_FAILURE;
00157     }
00158     
00159     context = xmlXPathNewContext(doc);
00160     
00161     
00162     
00163     if(root->ns != NULL)
00164     {
00165         xmlNsPtr ns = root->nsDef->next;
00166         
00167         xmlXPathRegisterNs(context, (const xmlChar *)root->nsDef->prefix, (const xmlChar *)root->nsDef->href);
00168         
00169         do
00170         {
00171             xmlXPathRegisterNs(context, (const xmlChar *)ns->prefix, (const xmlChar *)ns->href);
00172             
00173             ns = ns->next;
00174         }while(ns != NULL);
00175     }
00176     
00177     
00178 
00179 
00180 
00181 
00182 
00183 
00184     if(root->ns && !root->ns->prefix)
00185     {
00186         char *c, *start;
00187         char **nodeNameNsTab = NULL;
00188         unsigned int nb_tab  = 1, i, nb_tab_alloc = 10;
00189         
00190         xmlXPathRegisterNs(context, (const xmlChar *)"default", root->ns->href);
00191         
00192         c = start = (char *)nodeName;
00193         
00194         nodeNameNsTab = (char **)calloc(nb_tab_alloc, sizeof(char *));
00195         
00196         do
00197         {
00198             if((*c) == '/')
00199             {
00200                 nodeNameNsTab[nb_tab - 1] = (char *)calloc((c - start) + 1, 1);
00201                 strncpy(nodeNameNsTab[nb_tab - 1], (const char *)start, c - start);
00202                 if (nb_tab == nb_tab_alloc)
00203                 {
00204                     nb_tab_alloc += 10;
00205                     nodeNameNsTab = (char **)realloc(nodeNameNsTab, nb_tab_alloc * sizeof(char *));
00206                 }
00207                 nb_tab += 1;
00208                 start = c + 1;
00209             }
00210             
00211             ++c;
00212         }while((*c) != '\0');
00213         
00214         nodeNameNsTab[nb_tab - 1] = (char *)calloc((c - start) + 1, 1);
00215         strcpy(nodeNameNsTab[nb_tab - 1], (const char *)start);
00216         
00217         for(i = 0; i < nb_tab; ++i)
00218         {
00219             char *tmp = NULL;
00220             
00221             unsigned int detected = 0; 
00222             c = (char *)nodeNameNsTab[i];
00223             
00224             do
00225             {
00226                 if((*c) == ':' || (*c) == '@')
00227                 {
00228                     detected = 1;
00229                     start = c + 1;
00230                 }
00231                 ++c;
00232             }while((*c) != '\0');
00233             
00234             if(!detected)
00235             {
00236                 tmp = (char *)calloc(strlen(nodeNameNsTab[i]) + 9, 1);
00237                 strcpy(tmp, "default:");
00238                 strcpy(&tmp[8], (const char *)nodeNameNsTab[i]);
00239 
00240                 free(nodeNameNsTab[i]);
00241                 nodeNameNsTab[i] = tmp;
00242             }
00243         }
00244 
00245 
00246         length = strlen(xpathBase) + nb_tab;
00247         
00248         for(i = 0; i < nb_tab; ++i)
00249         {
00250             length += strlen(nodeNameNsTab[i]);
00251             
00252         }
00253         
00254         xpath  = (char *)calloc(length + 1, 1);
00255         
00256         strcpy(xpath, xpathBase);
00257         
00258         for(i = 0; i < nb_tab; ++i)
00259         {
00260             if(i)
00261                 strcat(xpath, "/");
00262             strcat(xpath, (const char *)nodeNameNsTab[i]);
00263             free(nodeNameNsTab[i]);
00264         }
00265         
00266         free(nodeNameNsTab);
00267         
00268         strcat(xpath, ")");
00269         
00270     }
00271     else
00272     {
00273         nodeNameNs = (char *)nodeName;
00274         
00275         length = strlen(xpathBase) + strlen(nodeNameNs) + 1;
00276         xpath  = (char *) calloc(length + 1, 1);
00277         
00278         if(xpath == NULL)
00279         { 
00280             printf("%s:%d: realloc failed.\n", __FILE__, __LINE__);
00281             *nodeNumber = 0;
00282             
00283             return EXIT_FAILURE;
00284         }
00285         
00286         strcpy(xpath, xpathBase);
00287         strcat(xpath, nodeNameNs);
00288         strcat(xpath, ")");
00289     }
00290     
00291     
00292     
00293     xpathExpr = (xmlChar*) xpath;
00294     result = xmlXPathEvalExpression(xpathExpr, context);
00295     
00296     free(xpath);
00297     
00298     if(result->type != XPATH_NUMBER)
00299     {
00300         *nodeNumber = 0;
00301 #ifdef DEBUG
00302         printf("getXmlNodeCount : No result\n");
00303 #endif
00304         xmlXPathFreeObject(result);
00305         xmlXPathFreeContext(context);
00306         
00307         return EXIT_NOTFOUND;
00308     }
00309     else
00310     {
00311         *nodeNumber = (int) result->floatval;
00312 #ifdef DEBUG
00313         printf("getXmlNodeCount : nodeNumber : %d\n", *nodeNumber);
00314 #endif
00315         xmlXPathFreeObject(result);
00316         xmlXPathFreeContext(context);
00317         
00318         return EXIT_FOUND;
00319     }  
00320     
00321     
00322 }  
00323 
00324 
00325 
00326 
00327 
00328 int
00329 getXmlInfo(int num_doc, char *xpathSearchString, char **xpathResultString)
00330 {
00331     xmlDocPtr doc;
00332     xmlXPathContextPtr context    = NULL;
00333     xmlChar            *xpathExpr = NULL;
00334     xmlXPathObjectPtr  result     = NULL;
00335     xmlNodeSetPtr      nodeSet    = NULL;
00336     xmlNodePtr         *curNode   = NULL;
00337     
00338     xmlNodePtr  root = NULL;
00339     doc = open_doc[num_doc];
00340     root = xmlDocGetRootElement(doc);
00341     
00342     context = xmlXPathNewContext(doc);
00343     
00344     
00345     if(root->ns != NULL)
00346     {
00347         xmlNsPtr ns = root->nsDef->next;
00348         
00349         xmlXPathRegisterNs(context, (const xmlChar *)root->nsDef->prefix, (const xmlChar *)root->nsDef->href);
00350         
00351         do
00352         {
00353             xmlXPathRegisterNs(context, (const xmlChar *)ns->prefix, (const xmlChar *)ns->href);
00354             
00355             ns = ns->next;
00356         }while(ns != NULL);
00357     }
00358     
00359     
00360     
00361 
00362 
00363 
00364 
00365 
00366 
00367     if(root->ns && !root->ns->prefix)
00368     {
00369         size_t length = 0;
00370         char *c, *start;
00371         char *xpath = NULL;
00372         char **nodeNameNsTab = NULL;
00373         unsigned int nb_tab  = 1, i, nb_tab_alloc = 10;
00374         
00375         xmlXPathRegisterNs(context, (const xmlChar *)"default", root->ns->href);
00376         printf("default namespace\n");
00377         c = (char *)xpathSearchString;
00378         
00379         c += 2;
00380         start = c;
00381         
00382         nodeNameNsTab = (char **)calloc(nb_tab_alloc, sizeof(char *));
00383         
00384         do
00385         {
00386             if((*c) == '/')
00387             {
00388                 nodeNameNsTab[nb_tab - 1] = (char *)calloc((c - start) + 1, 1);
00389                 strncpy(nodeNameNsTab[nb_tab - 1], (const char *)start, c - start);
00390                 if (nb_tab == nb_tab_alloc)
00391                 {
00392                     nb_tab_alloc += 10;
00393                     nodeNameNsTab = (char **)realloc(nodeNameNsTab, nb_tab_alloc * sizeof(char *));
00394                 }
00395                 nb_tab += 1;
00396                 start = c + 1;
00397             }
00398             
00399             ++c;
00400         }while((*c) != '\0');
00401         
00402         nodeNameNsTab[nb_tab - 1] = (char *)calloc((c - start) + 1, 1);
00403         strcpy(nodeNameNsTab[nb_tab - 1], (const char *)start);
00404         
00405         for(i = 0; i < nb_tab; ++i)
00406         {
00407             char *tmp = NULL;
00408             
00409             unsigned int detected = 0; 
00410             c = (char *)nodeNameNsTab[i];
00411             
00412             do
00413             {
00414                 if((*c) == ':' || (*c) == '@')
00415                 {
00416                     detected = 1;
00417                     start = c + 1;
00418                 }
00419                 ++c;
00420             }while((*c) != '\0');
00421             
00422             if(!detected)
00423             {
00424                 tmp = (char *)calloc(strlen(nodeNameNsTab[i]) + 9, 1);
00425                 strcpy(tmp, "default:");
00426                 strcpy(&tmp[8], (const char *)nodeNameNsTab[i]);
00427 
00428                 free(nodeNameNsTab[i]);
00429                 nodeNameNsTab[i] = tmp;
00430             }
00431         }
00432 
00433 
00434         length = nb_tab;
00435         
00436         for(i = 0; i < nb_tab; ++i)
00437         {
00438             length += strlen(nodeNameNsTab[i]);
00439             
00440         }
00441         
00442         xpath  = (char *)calloc(length + 3, 1);
00443         
00444         strcpy(xpath, "//");
00445         
00446         for(i = 0; i < nb_tab; ++i)
00447         {
00448             if(i)
00449                 strncat(xpath, "/", 1);
00450             strcat(xpath, (const char *)nodeNameNsTab[i]);
00451             free(nodeNameNsTab[i]);
00452         }
00453         
00454         free(nodeNameNsTab);
00455         
00456         xpathExpr = (xmlChar *)xpath;
00457     }
00458     else
00459     {
00460         xpathExpr = (xmlChar *) xpathSearchString;
00461     }
00462     
00463 #ifdef DEBUG
00464     printf("getXmlInfo : xpathExpr: %s\n", xpathExpr);
00465 #endif
00466     
00467     
00468     result  = xmlXPathEvalExpression(xpathExpr, context);
00469     nodeSet = result->nodesetval;
00470 
00471     
00472     if (xpathExpr != (xmlChar *) xpathSearchString)
00473         free(xpathExpr);
00474     
00475     if(xmlXPathNodeSetIsEmpty(nodeSet))
00476     {
00477 #ifdef DEBUG
00478       printf("getXmlInfo : No result here ! %d\n", EXIT_NOTFOUND);
00479 #endif
00480       *xpathResultString = NULL;
00481       xmlXPathFreeObject(result);
00482       xmlXPathFreeContext(context);
00483 
00484       return EXIT_NOTFOUND;
00485     }
00486     else
00487     {
00488       curNode = nodeSet->nodeTab;
00489       *xpathResultString = (char*) xmlNodeListGetString(doc, (*curNode)->children, 1);
00490 #ifdef DEBUG
00491       printf("getXmlInfo : xpathResultString: %s\n", *xpathResultString);
00492 #endif     
00493       xmlXPathFreeObject(result);
00494       xmlXPathFreeContext(context);
00495 
00496       return EXIT_FOUND;
00497     }
00498     
00499 }