15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Canonical XML implementation test program 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (http://www.w3.org/TR/2001/REC-xml-c14n-20010315) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Aleksey Sanin <aleksey@aleksey.com> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_UNISTD_H 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_STDLIB_H 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parser.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpath.h> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpathInternals.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/c14n.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void usage(const char *name) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Usage: %s <mode> <xml-file> [<xpath-expr>] [<inclusive-ns-list>]\n", 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "where <mode> is one of following:\n"); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--with-comments \t XML file canonicalization v1.0 w comments \n"); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--without-comments \t XML file canonicalization v1.0 w/o comments\n"); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--1-1-with-comments \t XML file canonicalization v1.1 w comments\n"); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--1-1-without-comments \t XML file canonicalization v1.1 w/o comments\n"); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--exc-with-comments \t Exclusive XML file canonicalization v1.0 w comments\n"); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--exc-without-comments\t Exclusive XML file canonicalization v1.0 w/o comments\n"); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlXPathObjectPtr 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)load_xpath_expr (xmlDocPtr parent_doc, const char* filename); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar **parse_list(xmlChar *str); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static void print_xpath_nodes(xmlNodeSetPtr nodes); */ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)test_c14n(const char* xml_filename, int with_comments, int mode, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* xpath_filename, xmlChar **inclusive_namespaces) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr xpath = NULL; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *result = NULL; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * build an XML tree from a the file; we need to add default 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * attributes and resolve all character and entities references 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSubstituteEntitiesDefault(1); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc == NULL) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check the document is of the right kind 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(xmlDocGetRootElement(doc) == NULL) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * load xpath file if specified 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(xpath_filename) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xpath = load_xpath_expr(doc, xpath_filename); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(xpath == NULL) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: unable to evaluate xpath expression\n"); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Canonical form 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlC14NDocDumpMemory(doc, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xpath) ? xpath->nodesetval : NULL, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode, inclusive_namespaces, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) with_comments, &result); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(ret >= 0) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(result != NULL) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write(1, result, ret); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(result); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(result != NULL) xmlFree(result); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cleanup 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(xpath != NULL) xmlXPathFreeObject(xpath); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = -1; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Init libxml 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlInitParser(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LIBXML_TEST_VERSION 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parse command line and process file 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( argc < 3 ) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Error: wrong number of arguments.\n"); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usage(argv[0]); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if(strcmp(argv[1], "--with-comments") == 0) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = test_c14n(argv[2], 1, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if(strcmp(argv[1], "--without-comments") == 0) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = test_c14n(argv[2], 0, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if(strcmp(argv[1], "--1-1-with-comments") == 0) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = test_c14n(argv[2], 1, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if(strcmp(argv[1], "--1-1-without-comments") == 0) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = test_c14n(argv[2], 0, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if(strcmp(argv[1], "--exc-with-comments") == 0) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **list; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* load exclusive namespace from command line */ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = test_c14n(argv[2], 1, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(list != NULL) xmlFree(list); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if(strcmp(argv[1], "--exc-without-comments") == 0) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **list; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* load exclusive namespace from command line */ 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = test_c14n(argv[2], 0, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(list != NULL) xmlFree(list); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Error: bad option.\n"); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usage(argv[0]); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Shutdown libxml 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlCleanupParser(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMemoryDump(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return((ret >= 0) ? 0 : 1); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Macro used to grow the current buffer. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define growBufferReentrant() { \ 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size *= 2; \ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer = (xmlChar **) \ 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRealloc(buffer, buffer_size * sizeof(xmlChar*)); \ 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer == NULL) { \ 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("realloc failed"); \ 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); \ 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar ** 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_list(xmlChar *str) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **buffer; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar **out = NULL; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_size = 0; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(str == NULL) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = xmlStrlen(str); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if((str[0] == '\'') && (str[len - 1] == '\'')) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[len - 1] = '\0'; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str++; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * allocate an translation buffer. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size = 1000; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*)); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer == NULL) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("malloc failed"); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = buffer; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while(*str != '\0') { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (out - buffer > buffer_size - 10) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int indx = out - buffer; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) growBufferReentrant(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = &buffer[indx]; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*out++) = str; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while(*str != ',' && *str != '\0') ++str; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(*str == ',') *(str++) = '\0'; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*out) = NULL; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlXPathObjectPtr 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)load_xpath_expr (xmlDocPtr parent_doc, const char* filename) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr xpath; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *expr; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathContextPtr ctx; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ns; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * load XPath expr as a file 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSubstituteEntitiesDefault(1); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc == NULL) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check the document is of the right kind 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(xmlDocGetRootElement(doc) == NULL) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: empty document for file \"%s\"\n", filename); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = doc->children; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = node->next; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(node == NULL) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: XPath element expected in the file \"%s\"\n", filename); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expr = xmlNodeGetContent(node); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(expr == NULL) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx = xmlXPathNewContext(parent_doc); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(ctx == NULL) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: unable to create new context\n"); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(expr); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Register namespaces 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = node->nsDef; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while(ns != NULL) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(expr); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeContext(ctx); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = ns->next; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Evaluate xpath 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xpath = xmlXPathEvalExpression(expr, ctx); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(xpath == NULL) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr,"Error: unable to evaluate xpath expression\n"); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(expr); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeContext(ctx); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* print_xpath_nodes(xpath->nodesetval); */ 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(expr); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeContext(ctx); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xpath); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)print_xpath_nodes(xmlNodeSetPtr nodes) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr cur; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(nodes == NULL ){ 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Error: no nodes set defined\n"); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Nodes Set:\n-----\n"); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i = 0; i < nodes->nodeNr; ++i) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ns; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = (xmlNsPtr)nodes->nodeTab[i]; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = (xmlNodePtr)ns->next; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "namespace \"%s\"=\"%s\" for node %s:%s\n", 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns->prefix, ns->href, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = nodes->nodeTab[i]; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "element node \"%s:%s\"\n", 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = nodes->nodeTab[i]; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "node \"%s\": type %d\n", cur->name, cur->type); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s : XPath/Canonicalization and output support not compiled in\n", argv[0]); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_C14N_ENABLED */ 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365