Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygentestC14N.c
Go to the documentation of this file.
00001 /* 00002 * Canonical XML implementation test program 00003 * (http://www.w3.org/TR/2001/REC-xml-c14n-20010315) 00004 * 00005 * See Copyright for the status of this software. 00006 * 00007 * Author: Aleksey Sanin <aleksey@aleksey.com> 00008 */ 00009 #include "libxml.h" 00010 #if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) 00011 00012 #include <stdio.h> 00013 #include <string.h> 00014 #ifdef HAVE_UNISTD_H 00015 #include <unistd.h> 00016 #endif 00017 #ifdef HAVE_STDLIB_H 00018 #include <stdlib.h> 00019 #endif 00020 00021 #include <libxml/xmlmemory.h> 00022 #include <libxml/parser.h> 00023 #include <libxml/xpath.h> 00024 #include <libxml/xpathInternals.h> 00025 00026 #include <libxml/c14n.h> 00027 00028 00029 static void usage(const char *name) { 00030 fprintf(stderr, 00031 "Usage: %s <mode> <xml-file> [<xpath-expr>] [<inclusive-ns-list>]\n", 00032 name); 00033 fprintf(stderr, "where <mode> is one of following:\n"); 00034 fprintf(stderr, 00035 "--with-comments \t XML file canonicalization v1.0 w comments \n"); 00036 fprintf(stderr, 00037 "--without-comments \t XML file canonicalization v1.0 w/o comments\n"); 00038 fprintf(stderr, 00039 "--1-1-with-comments \t XML file canonicalization v1.1 w comments\n"); 00040 fprintf(stderr, 00041 "--1-1-without-comments \t XML file canonicalization v1.1 w/o comments\n"); 00042 fprintf(stderr, 00043 "--exc-with-comments \t Exclusive XML file canonicalization v1.0 w comments\n"); 00044 fprintf(stderr, 00045 "--exc-without-comments\t Exclusive XML file canonicalization v1.0 w/o comments\n"); 00046 } 00047 00048 static xmlXPathObjectPtr 00049 load_xpath_expr (xmlDocPtr parent_doc, const char* filename); 00050 00051 static xmlChar **parse_list(xmlChar *str); 00052 00053 /* static void print_xpath_nodes(xmlNodeSetPtr nodes); */ 00054 00055 static int 00056 test_c14n(const char* xml_filename, int with_comments, int mode, 00057 const char* xpath_filename, xmlChar **inclusive_namespaces) { 00058 xmlDocPtr doc; 00059 xmlXPathObjectPtr xpath = NULL; 00060 xmlChar *result = NULL; 00061 int ret; 00062 00063 /* 00064 * build an XML tree from a the file; we need to add default 00065 * attributes and resolve all character and entities references 00066 */ 00067 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 00068 xmlSubstituteEntitiesDefault(1); 00069 00070 doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT); 00071 if (doc == NULL) { 00072 fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename); 00073 return(-1); 00074 } 00075 00076 /* 00077 * Check the document is of the right kind 00078 */ 00079 if(xmlDocGetRootElement(doc) == NULL) { 00080 fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename); 00081 xmlFreeDoc(doc); 00082 return(-1); 00083 } 00084 00085 /* 00086 * load xpath file if specified 00087 */ 00088 if(xpath_filename) { 00089 xpath = load_xpath_expr(doc, xpath_filename); 00090 if(xpath == NULL) { 00091 fprintf(stderr,"Error: unable to evaluate xpath expression\n"); 00092 xmlFreeDoc(doc); 00093 return(-1); 00094 } 00095 } 00096 00097 /* 00098 * Canonical form 00099 */ 00100 /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */ 00101 ret = xmlC14NDocDumpMemory(doc, 00102 (xpath) ? xpath->nodesetval : NULL, 00103 mode, inclusive_namespaces, 00104 with_comments, &result); 00105 if(ret >= 0) { 00106 if(result != NULL) { 00107 write(1, result, ret); 00108 xmlFree(result); 00109 } 00110 } else { 00111 fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret); 00112 if(result != NULL) xmlFree(result); 00113 xmlFreeDoc(doc); 00114 return(-1); 00115 } 00116 00117 /* 00118 * Cleanup 00119 */ 00120 if(xpath != NULL) xmlXPathFreeObject(xpath); 00121 xmlFreeDoc(doc); 00122 00123 return(ret); 00124 } 00125 00126 int main(int argc, char **argv) { 00127 int ret = -1; 00128 00129 /* 00130 * Init libxml 00131 */ 00132 xmlInitParser(); 00133 LIBXML_TEST_VERSION 00134 00135 /* 00136 * Parse command line and process file 00137 */ 00138 if( argc < 3 ) { 00139 fprintf(stderr, "Error: wrong number of arguments.\n"); 00140 usage(argv[0]); 00141 } else if(strcmp(argv[1], "--with-comments") == 0) { 00142 ret = test_c14n(argv[2], 1, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL); 00143 } else if(strcmp(argv[1], "--without-comments") == 0) { 00144 ret = test_c14n(argv[2], 0, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL); 00145 } else if(strcmp(argv[1], "--1-1-with-comments") == 0) { 00146 ret = test_c14n(argv[2], 1, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL); 00147 } else if(strcmp(argv[1], "--1-1-without-comments") == 0) { 00148 ret = test_c14n(argv[2], 0, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL); 00149 } else if(strcmp(argv[1], "--exc-with-comments") == 0) { 00150 xmlChar **list; 00151 00152 /* load exclusive namespace from command line */ 00153 list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL; 00154 ret = test_c14n(argv[2], 1, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list); 00155 if(list != NULL) xmlFree(list); 00156 } else if(strcmp(argv[1], "--exc-without-comments") == 0) { 00157 xmlChar **list; 00158 00159 /* load exclusive namespace from command line */ 00160 list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL; 00161 ret = test_c14n(argv[2], 0, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list); 00162 if(list != NULL) xmlFree(list); 00163 } else { 00164 fprintf(stderr, "Error: bad option.\n"); 00165 usage(argv[0]); 00166 } 00167 00168 /* 00169 * Shutdown libxml 00170 */ 00171 xmlCleanupParser(); 00172 xmlMemoryDump(); 00173 00174 return((ret >= 0) ? 0 : 1); 00175 } 00176 00177 /* 00178 * Macro used to grow the current buffer. 00179 */ 00180 #define growBufferReentrant() { \ 00181 buffer_size *= 2; \ 00182 buffer = (xmlChar **) \ 00183 xmlRealloc(buffer, buffer_size * sizeof(xmlChar*)); \ 00184 if (buffer == NULL) { \ 00185 perror("realloc failed"); \ 00186 return(NULL); \ 00187 } \ 00188 } 00189 00190 static xmlChar ** 00191 parse_list(xmlChar *str) { 00192 xmlChar **buffer; 00193 xmlChar **out = NULL; 00194 int buffer_size = 0; 00195 int len; 00196 00197 if(str == NULL) { 00198 return(NULL); 00199 } 00200 00201 len = xmlStrlen(str); 00202 if((str[0] == '\'') && (str[len - 1] == '\'')) { 00203 str[len - 1] = '\0'; 00204 str++; 00205 } 00206 /* 00207 * allocate an translation buffer. 00208 */ 00209 buffer_size = 1000; 00210 buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*)); 00211 if (buffer == NULL) { 00212 perror("malloc failed"); 00213 return(NULL); 00214 } 00215 out = buffer; 00216 00217 while(*str != '\0') { 00218 if (out - buffer > buffer_size - 10) { 00219 int indx = out - buffer; 00220 00221 growBufferReentrant(); 00222 out = &buffer[indx]; 00223 } 00224 (*out++) = str; 00225 while(*str != ',' && *str != '\0') ++str; 00226 if(*str == ',') *(str++) = '\0'; 00227 } 00228 (*out) = NULL; 00229 return buffer; 00230 } 00231 00232 static xmlXPathObjectPtr 00233 load_xpath_expr (xmlDocPtr parent_doc, const char* filename) { 00234 xmlXPathObjectPtr xpath; 00235 xmlDocPtr doc; 00236 xmlChar *expr; 00237 xmlXPathContextPtr ctx; 00238 xmlNodePtr node; 00239 xmlNsPtr ns; 00240 00241 /* 00242 * load XPath expr as a file 00243 */ 00244 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 00245 xmlSubstituteEntitiesDefault(1); 00246 00247 doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT); 00248 if (doc == NULL) { 00249 fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename); 00250 return(NULL); 00251 } 00252 00253 /* 00254 * Check the document is of the right kind 00255 */ 00256 if(xmlDocGetRootElement(doc) == NULL) { 00257 fprintf(stderr,"Error: empty document for file \"%s\"\n", filename); 00258 xmlFreeDoc(doc); 00259 return(NULL); 00260 } 00261 00262 node = doc->children; 00263 while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) { 00264 node = node->next; 00265 } 00266 00267 if(node == NULL) { 00268 fprintf(stderr,"Error: XPath element expected in the file \"%s\"\n", filename); 00269 xmlFreeDoc(doc); 00270 return(NULL); 00271 } 00272 00273 expr = xmlNodeGetContent(node); 00274 if(expr == NULL) { 00275 fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename); 00276 xmlFreeDoc(doc); 00277 return(NULL); 00278 } 00279 00280 ctx = xmlXPathNewContext(parent_doc); 00281 if(ctx == NULL) { 00282 fprintf(stderr,"Error: unable to create new context\n"); 00283 xmlFree(expr); 00284 xmlFreeDoc(doc); 00285 return(NULL); 00286 } 00287 00288 /* 00289 * Register namespaces 00290 */ 00291 ns = node->nsDef; 00292 while(ns != NULL) { 00293 if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) { 00294 fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href); 00295 xmlFree(expr); 00296 xmlXPathFreeContext(ctx); 00297 xmlFreeDoc(doc); 00298 return(NULL); 00299 } 00300 ns = ns->next; 00301 } 00302 00303 /* 00304 * Evaluate xpath 00305 */ 00306 xpath = xmlXPathEvalExpression(expr, ctx); 00307 if(xpath == NULL) { 00308 fprintf(stderr,"Error: unable to evaluate xpath expression\n"); 00309 xmlFree(expr); 00310 xmlXPathFreeContext(ctx); 00311 xmlFreeDoc(doc); 00312 return(NULL); 00313 } 00314 00315 /* print_xpath_nodes(xpath->nodesetval); */ 00316 00317 xmlFree(expr); 00318 xmlXPathFreeContext(ctx); 00319 xmlFreeDoc(doc); 00320 return(xpath); 00321 } 00322 00323 /* 00324 static void 00325 print_xpath_nodes(xmlNodeSetPtr nodes) { 00326 xmlNodePtr cur; 00327 int i; 00328 00329 if(nodes == NULL ){ 00330 fprintf(stderr, "Error: no nodes set defined\n"); 00331 return; 00332 } 00333 00334 fprintf(stderr, "Nodes Set:\n-----\n"); 00335 for(i = 0; i < nodes->nodeNr; ++i) { 00336 if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) { 00337 xmlNsPtr ns; 00338 00339 ns = (xmlNsPtr)nodes->nodeTab[i]; 00340 cur = (xmlNodePtr)ns->next; 00341 fprintf(stderr, "namespace \"%s\"=\"%s\" for node %s:%s\n", 00342 ns->prefix, ns->href, 00343 (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name); 00344 } else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { 00345 cur = nodes->nodeTab[i]; 00346 fprintf(stderr, "element node \"%s:%s\"\n", 00347 (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name); 00348 } else { 00349 cur = nodes->nodeTab[i]; 00350 fprintf(stderr, "node \"%s\": type %d\n", cur->name, cur->type); 00351 } 00352 } 00353 } 00354 */ 00355 00356 #else 00357 #include <stdio.h> 00358 int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { 00359 printf("%s : XPath/Canonicalization and output support not compiled in\n", argv[0]); 00360 return(0); 00361 } 00362 #endif /* LIBXML_C14N_ENABLED */ 00363 00364 Generated on Thu May 24 2012 04:35:07 for ReactOS by
1.7.6.1
|