1044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/* 2044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Canonical XML implementation test program 3044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * (http://www.w3.org/TR/2001/REC-xml-c14n-20010315) 4044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * 5044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * See Copyright for the status of this software. 6f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * 7044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Author: Aleksey Sanin <aleksey@aleksey.com> 8044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 9044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include "libxml.h" 10a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) 11044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 12044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <stdio.h> 13044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <string.h> 14414f269a4ff6f8c8ccbf903a3386c91b2d8bc96cEric Zurcher#ifndef STDOUT_FILENO 15044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#ifdef HAVE_UNISTD_H 16044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <unistd.h> 17b8428a2a25e6b0aff8ca33dd3d34c5c38fdb8749Tay Ray Chuan#else 18b8428a2a25e6b0aff8ca33dd3d34c5c38fdb8749Tay Ray Chuan#define STDOUT_FILENO fileno(stdout) 19b8428a2a25e6b0aff8ca33dd3d34c5c38fdb8749Tay Ray Chuan#endif /* HAVE_UNISTD_H */ 20414f269a4ff6f8c8ccbf903a3386c91b2d8bc96cEric Zurcher#endif 21044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#ifdef HAVE_STDLIB_H 22044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <stdlib.h> 23044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#endif 24044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 25044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/xmlmemory.h> 26044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/parser.h> 27044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/xpath.h> 28044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/xpathInternals.h> 29044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 30044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <libxml/c14n.h> 31044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 32044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 33044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardstatic void usage(const char *name) { 34044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, 35044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard "Usage: %s <mode> <xml-file> [<xpath-expr>] [<inclusive-ns-list>]\n", 36044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard name); 37044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, "where <mode> is one of following:\n"); 38044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, 39838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin "--with-comments \t XML file canonicalization v1.0 w comments \n"); 40044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, 41838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin "--without-comments \t XML file canonicalization v1.0 w/o comments\n"); 42044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, 43838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin "--1-1-with-comments \t XML file canonicalization v1.1 w comments\n"); 44044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, 45838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin "--1-1-without-comments \t XML file canonicalization v1.1 w/o comments\n"); 46838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin fprintf(stderr, 47838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin "--exc-with-comments \t Exclusive XML file canonicalization v1.0 w comments\n"); 48838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin fprintf(stderr, 49838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin "--exc-without-comments\t Exclusive XML file canonicalization v1.0 w/o comments\n"); 50044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 51044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 52fe8aab98438d36bfc3c7c2080ee1a457d9202d1fDaniel Veillardstatic xmlXPathObjectPtr 53044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardload_xpath_expr (xmlDocPtr parent_doc, const char* filename); 54044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 55fe8aab98438d36bfc3c7c2080ee1a457d9202d1fDaniel Veillardstatic xmlChar **parse_list(xmlChar *str); 56044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 57c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack/* static void print_xpath_nodes(xmlNodeSetPtr nodes); */ 58044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 59f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardstatic int 60838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanintest_c14n(const char* xml_filename, int with_comments, int mode, 61044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard const char* xpath_filename, xmlChar **inclusive_namespaces) { 62044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlDocPtr doc; 63f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlXPathObjectPtr xpath = NULL; 64044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlChar *result = NULL; 65044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int ret; 66044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 67044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 68044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * build an XML tree from a the file; we need to add default 69044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * attributes and resolve all character and entities references 70044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 71044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 72044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlSubstituteEntitiesDefault(1); 73044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 74bca3ad25f93b7895c4c89ea38551a2873cbbd3e1Daniel Veillard doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT); 75044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (doc == NULL) { 76044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename); 77044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(-1); 78044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 79f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 80044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 81044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Check the document is of the right kind 82f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 83044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(xmlDocGetRootElement(doc) == NULL) { 84044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename); 85044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeDoc(doc); 86044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(-1); 87044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 88044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 89f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard /* 90f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * load xpath file if specified 91044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 92044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(xpath_filename) { 93044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xpath = load_xpath_expr(doc, xpath_filename); 94044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(xpath == NULL) { 95044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: unable to evaluate xpath expression\n"); 96f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFreeDoc(doc); 97044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(-1); 98044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 99044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 100044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 101044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 102044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Canonical form 103f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 104044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */ 105f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ret = xmlC14NDocDumpMemory(doc, 106f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard (xpath) ? xpath->nodesetval : NULL, 107838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin mode, inclusive_namespaces, 108044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard with_comments, &result); 109044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(ret >= 0) { 110044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(result != NULL) { 111dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost if (write(STDOUT_FILENO, result, ret) == -1) { 112dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost fprintf(stderr, "Can't write data\n"); 113dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost } 114dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost xmlFree(result); 115044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 116044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 117044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret); 118044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(result != NULL) xmlFree(result); 119f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFreeDoc(doc); 120044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(-1); 121044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 122f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 123044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 124044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Cleanup 125f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 126044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(xpath != NULL) xmlXPathFreeObject(xpath); 127f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFreeDoc(doc); 128044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 129044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(ret); 130044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 131044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 132044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardint main(int argc, char **argv) { 133044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int ret = -1; 134f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 135044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 136044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Init libxml 137f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 138044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlInitParser(); 139044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard LIBXML_TEST_VERSION 140044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 141044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 142044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Parse command line and process file 143044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 144044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if( argc < 3 ) { 145044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, "Error: wrong number of arguments.\n"); 146044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard usage(argv[0]); 147044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if(strcmp(argv[1], "--with-comments") == 0) { 148838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin ret = test_c14n(argv[2], 1, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL); 149044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if(strcmp(argv[1], "--without-comments") == 0) { 150838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin ret = test_c14n(argv[2], 0, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL); 151838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin } else if(strcmp(argv[1], "--1-1-with-comments") == 0) { 152838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin ret = test_c14n(argv[2], 1, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL); 153838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin } else if(strcmp(argv[1], "--1-1-without-comments") == 0) { 154838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin ret = test_c14n(argv[2], 0, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL); 155044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if(strcmp(argv[1], "--exc-with-comments") == 0) { 156044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlChar **list; 157f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 158044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* load exclusive namespace from command line */ 159044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL; 160838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin ret = test_c14n(argv[2], 1, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list); 161044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(list != NULL) xmlFree(list); 162044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else if(strcmp(argv[1], "--exc-without-comments") == 0) { 163044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlChar **list; 164f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 165044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* load exclusive namespace from command line */ 166044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL; 167838682478cf89ddcbda294d9557c72813135fc7aAleksey Sanin ret = test_c14n(argv[2], 0, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list); 168044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(list != NULL) xmlFree(list); 169044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } else { 170044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, "Error: bad option.\n"); 171044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard usage(argv[0]); 172044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 173044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 174f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard /* 175044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Shutdown libxml 176044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 177044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlCleanupParser(); 178044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlMemoryDump(); 17913cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard 180044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return((ret >= 0) ? 0 : 1); 181044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 182044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 183044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard/* 184044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Macro used to grow the current buffer. 185044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 186044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#define growBufferReentrant() { \ 187044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard buffer_size *= 2; \ 188044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard buffer = (xmlChar **) \ 18913cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard xmlRealloc(buffer, buffer_size * sizeof(xmlChar*)); \ 190044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (buffer == NULL) { \ 191044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard perror("realloc failed"); \ 192044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); \ 193044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } \ 194044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 195044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 19601c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillardstatic xmlChar ** 19701c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillardparse_list(xmlChar *str) { 198044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlChar **buffer; 199044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlChar **out = NULL; 200044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int buffer_size = 0; 201f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin int len; 202044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 203044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(str == NULL) { 204044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 205044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 206044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 207118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard len = xmlStrlen(str); 208f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin if((str[0] == '\'') && (str[len - 1] == '\'')) { 209f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin str[len - 1] = '\0'; 210f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin str++; 211f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin } 212044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 213044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * allocate an translation buffer. 214044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 215044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard buffer_size = 1000; 216044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*)); 217044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (buffer == NULL) { 218044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard perror("malloc failed"); 219044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 220044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 221044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard out = buffer; 22213cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard 223044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard while(*str != '\0') { 224044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (out - buffer > buffer_size - 10) { 225044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int indx = out - buffer; 226044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 227044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard growBufferReentrant(); 228044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard out = &buffer[indx]; 229044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 230044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (*out++) = str; 231044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard while(*str != ',' && *str != '\0') ++str; 232044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(*str == ',') *(str++) = '\0'; 233044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 234044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard (*out) = NULL; 235044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return buffer; 236044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 237044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 23801c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillardstatic xmlXPathObjectPtr 239044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillardload_xpath_expr (xmlDocPtr parent_doc, const char* filename) { 240f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlXPathObjectPtr xpath; 241044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlDocPtr doc; 242044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlChar *expr; 243f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlXPathContextPtr ctx; 244044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNodePtr node; 245044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNsPtr ns; 246f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 247044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 248044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * load XPath expr as a file 249044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 250044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; 251044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlSubstituteEntitiesDefault(1); 252044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 253bca3ad25f93b7895c4c89ea38551a2873cbbd3e1Daniel Veillard doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT); 254044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if (doc == NULL) { 255044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename); 256044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 257044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 258f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 259044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 260044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Check the document is of the right kind 261f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 262044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(xmlDocGetRootElement(doc) == NULL) { 263044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: empty document for file \"%s\"\n", filename); 264044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeDoc(doc); 265044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 266044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 267044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 268044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard node = doc->children; 269044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) { 270044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard node = node->next; 271044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 272f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 273f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if(node == NULL) { 274044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: XPath element expected in the file \"%s\"\n", filename); 275044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeDoc(doc); 276044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 277044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 278044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 279044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard expr = xmlNodeGetContent(node); 280044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(expr == NULL) { 281044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename); 282044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlFreeDoc(doc); 283044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 284044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 285044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 286044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ctx = xmlXPathNewContext(parent_doc); 287044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(ctx == NULL) { 288044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: unable to create new context\n"); 289f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFree(expr); 290f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFreeDoc(doc); 291044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 292044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 293044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 294044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard /* 295044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Register namespaces 296044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 297044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns = node->nsDef; 298044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard while(ns != NULL) { 299044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) { 300044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href); 301f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFree(expr); 302f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlXPathFreeContext(ctx); 303f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFreeDoc(doc); 304044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 305044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 306044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard ns = ns->next; 307044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 308044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 309f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard /* 310044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard * Evaluate xpath 311044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard */ 312044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xpath = xmlXPathEvalExpression(expr, ctx); 313044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard if(xpath == NULL) { 314044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr,"Error: unable to evaluate xpath expression\n"); 315f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFree(expr); 316f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlXPathFreeContext(ctx); 317f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFreeDoc(doc); 318044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(NULL); 319044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 320044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 321f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin /* print_xpath_nodes(xpath->nodesetval); */ 322044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 323f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFree(expr); 324f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlXPathFreeContext(ctx); 325f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlFreeDoc(doc); 326044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(xpath); 327044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 328044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 329c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack/* 33001c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillardstatic void 331f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Saninprint_xpath_nodes(xmlNodeSetPtr nodes) { 332044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard xmlNodePtr cur; 333044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard int i; 334f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 335f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if(nodes == NULL ){ 336044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard fprintf(stderr, "Error: no nodes set defined\n"); 337044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return; 338044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 339f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 340f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin fprintf(stderr, "Nodes Set:\n-----\n"); 341f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin for(i = 0; i < nodes->nodeNr; ++i) { 342f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) { 343f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin xmlNsPtr ns; 344f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 345f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin ns = (xmlNsPtr)nodes->nodeTab[i]; 346f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin cur = (xmlNodePtr)ns->next; 347f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard fprintf(stderr, "namespace \"%s\"=\"%s\" for node %s:%s\n", 348f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin ns->prefix, ns->href, 349f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name); 350f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin } else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { 351f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard cur = nodes->nodeTab[i]; 352f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard fprintf(stderr, "element node \"%s:%s\"\n", 353f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name); 354f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin } else { 355f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard cur = nodes->nodeTab[i]; 356f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin fprintf(stderr, "node \"%s\": type %d\n", cur->name, cur->type); 357f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin } 358044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard } 359044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 360c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack*/ 361f8cb6dda89d3866c796c8cfb2ba377d12822bf24Aleksey Sanin 362044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#else 363044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#include <stdio.h> 364a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillardint main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { 365a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard printf("%s : XPath/Canonicalization and output support not compiled in\n", argv[0]); 366044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard return(0); 367044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard} 368044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard#endif /* LIBXML_C14N_ENABLED */ 369044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 370044fc6b7476798cbb95277b4905e5111d7c2775dDaniel Veillard 371