#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include "sasa_c_xml.h"
Go to the source code of this file.
Defines | |
#define | MAX_OPEN_DOCUMENTS 100 |
Functions/Subroutines | |
int | sasaOpenXml (const char *filename) |
int | sasaCloseXml (int num_doc) |
int | getXmlNodeCount (int num_doc, const char *nodeName, int *nodeNumber) |
int | getXmlInfo (int num_doc, char *xpathSearchString, char **xpathResultString) |
Variables | |
xmlDocPtr | open_doc [MAX_OPEN_DOCUMENTS] |
int | nb_open_doc = -1 |
#define MAX_OPEN_DOCUMENTS 100 |
Definition at line 55 of file sasa_c_xml.c.
Referenced by sasaOpenXml().
int getXmlInfo | ( | int | num_doc, | |
char * | xpathSearchString, | |||
char ** | xpathResultString | |||
) |
Definition at line 329 of file sasa_c_xml.c.
References doc, EXIT_FOUND, EXIT_NOTFOUND, i, length, and open_doc.
Referenced by sasa_c_get_attribute(), sasa_c_get_element_c(), sasa_c_get_element_d(), and sasa_c_get_element_i().
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 /* Register prefixed namespace(s) defined in the root node */ 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 /* If a default namespace is defined 00361 * 00362 * IMPORTANT: XPath 1.0 has no concept of a default namespace. Unprefixed names in XPath only match names which have no namespace. 00363 * So, if the document uses a default namespace, it is required to associate a non-empty prefix with the default namespace 00364 * via register-namespace and add that prefix to names in XPath expressions intended to match nodes in the default namespace. 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 /* : and @ punctuation mark detection */ 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 /* evaluate the XPath expression in the given context */ 00468 result = xmlXPathEvalExpression(xpathExpr, context); 00469 nodeSet = result->nodesetval; 00470 00471 /* free allocated memory if xpathExpr was computed */ 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 }
int getXmlNodeCount | ( | int | num_doc, | |
const char * | nodeName, | |||
int * | nodeNumber | |||
) |
Definition at line 128 of file sasa_c_xml.c.
References doc, EXIT_FAILURE, EXIT_FOUND, EXIT_NOTFOUND, i, length, and open_doc.
Referenced by sasa_c_get_number().
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 /* Register prefixed namespace(s) defined in the root node */ 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 /* If a default namespace is defined 00178 * 00179 * IMPORTANT: XPath 1.0 has no concept of a default namespace. Unprefixed names in XPath only match names which have no namespace. 00180 * So, if the document uses a default namespace, it is required to associate a non-empty prefix with the default namespace 00181 * via register-namespace and add that prefix to names in XPath expressions intended to match nodes in the default namespace. 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 /* : and @ punctuation mark detection */ 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 } /* end sasaGetXmlNodeCount */
int sasaCloseXml | ( | int | num_doc | ) |
Definition at line 107 of file sasa_c_xml.c.
References doc, EXIT_SUCCESS, nb_open_doc, and open_doc.
Referenced by sasa_c_close().
00108 { 00109 xmlDocPtr doc; 00110 00111 /* free the document */ 00112 doc = open_doc[num_doc]; 00113 xmlFreeDoc(doc); 00114 00115 /* reset pointer to open doc */ 00116 open_doc[num_doc] = NULL; 00117 nb_open_doc -= 1; 00118 00119 return EXIT_SUCCESS; 00120 00121 } /* end sasaCloseXml */
int sasaOpenXml | ( | const char * | filename | ) |
Definition at line 61 of file sasa_c_xml.c.
References doc, i, MAX_OPEN_DOCUMENTS, nb_open_doc, open_doc, and mpp_mod_oa::stderr().
Referenced by sasa_c_read_file().
00062 { 00063 xmlDocPtr doc; 00064 int num_doc; 00065 int i; 00066 00067 /* Initialise table if not yet done */ 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 /* parse an XML file and build a tree */ 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 /* Look for an empty slot in open doc table */ 00094 for (num_doc = 0; open_doc[num_doc] != NULL; num_doc += 1) 00095 ; 00096 /* store pointer to open doc into slot */ 00097 open_doc[num_doc] = doc; 00098 nb_open_doc += 1; 00099 00100 return num_doc; 00101 } 00102 } 00103 } /* end sasaOpenXml */
int nb_open_doc = -1 |
Definition at line 58 of file sasa_c_xml.c.
Referenced by sasaCloseXml(), and sasaOpenXml().
xmlDocPtr open_doc[MAX_OPEN_DOCUMENTS] |
Definition at line 56 of file sasa_c_xml.c.
Referenced by getXmlInfo(), getXmlNodeCount(), sasaCloseXml(), and sasaOpenXml().