Annotation of embedaddon/libxml2/doc/examples/xpath1.c, revision 1.1

1.1     ! misho       1: /** 
        !             2:  * section:    XPath
        !             3:  * synopsis:   Evaluate XPath expression and prints result node set.
        !             4:  * purpose:    Shows how to evaluate XPath expression and register 
        !             5:  *             known namespaces in XPath context.
        !             6:  * usage:      xpath1 <xml-file> <xpath-expr> [<known-ns-list>]
        !             7:  * test: ./xpath1 test3.xml '//child2' > xpath1.tmp ; diff xpath1.tmp xpath1.res ; rm xpath1.tmp
        !             8:  * author:     Aleksey Sanin
        !             9:  * copy:       see Copyright for the status of this software.
        !            10:  */
        !            11: #include <stdlib.h>
        !            12: #include <stdio.h>
        !            13: #include <string.h>
        !            14: #include <assert.h>
        !            15: 
        !            16: #include <libxml/tree.h>
        !            17: #include <libxml/parser.h>
        !            18: #include <libxml/xpath.h>
        !            19: #include <libxml/xpathInternals.h>
        !            20: 
        !            21: #if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_SAX1_ENABLED)
        !            22: 
        !            23: 
        !            24: static void usage(const char *name);
        !            25: int  execute_xpath_expression(const char* filename, const xmlChar* xpathExpr, const xmlChar* nsList);
        !            26: int  register_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList);
        !            27: void print_xpath_nodes(xmlNodeSetPtr nodes, FILE* output);
        !            28: 
        !            29: int 
        !            30: main(int argc, char **argv) {
        !            31:     /* Parse command line and process file */
        !            32:     if((argc < 3) || (argc > 4)) {
        !            33:        fprintf(stderr, "Error: wrong number of arguments.\n");
        !            34:        usage(argv[0]);
        !            35:        return(-1);
        !            36:     } 
        !            37:     
        !            38:     /* Init libxml */     
        !            39:     xmlInitParser();
        !            40:     LIBXML_TEST_VERSION
        !            41: 
        !            42:     /* Do the main job */
        !            43:     if(execute_xpath_expression(argv[1], BAD_CAST argv[2], (argc > 3) ? BAD_CAST argv[3] : NULL) < 0) {
        !            44:        usage(argv[0]);
        !            45:        return(-1);
        !            46:     }
        !            47: 
        !            48:     /* Shutdown libxml */
        !            49:     xmlCleanupParser();
        !            50:     
        !            51:     /*
        !            52:      * this is to debug memory for regression tests
        !            53:      */
        !            54:     xmlMemoryDump();
        !            55:     return 0;
        !            56: }
        !            57: 
        !            58: /**
        !            59:  * usage:
        !            60:  * @name:              the program name.
        !            61:  *
        !            62:  * Prints usage information.
        !            63:  */
        !            64: static void 
        !            65: usage(const char *name) {
        !            66:     assert(name);
        !            67:     
        !            68:     fprintf(stderr, "Usage: %s <xml-file> <xpath-expr> [<known-ns-list>]\n", name);
        !            69:     fprintf(stderr, "where <known-ns-list> is a list of known namespaces\n");
        !            70:     fprintf(stderr, "in \"<prefix1>=<href1> <prefix2>=href2> ...\" format\n");
        !            71: }
        !            72: 
        !            73: /**
        !            74:  * execute_xpath_expression:
        !            75:  * @filename:          the input XML filename.
        !            76:  * @xpathExpr:         the xpath expression for evaluation.
        !            77:  * @nsList:            the optional list of known namespaces in 
        !            78:  *                     "<prefix1>=<href1> <prefix2>=href2> ..." format.
        !            79:  *
        !            80:  * Parses input XML file, evaluates XPath expression and prints results.
        !            81:  *
        !            82:  * Returns 0 on success and a negative value otherwise.
        !            83:  */
        !            84: int 
        !            85: execute_xpath_expression(const char* filename, const xmlChar* xpathExpr, const xmlChar* nsList) {
        !            86:     xmlDocPtr doc;
        !            87:     xmlXPathContextPtr xpathCtx; 
        !            88:     xmlXPathObjectPtr xpathObj; 
        !            89:     
        !            90:     assert(filename);
        !            91:     assert(xpathExpr);
        !            92: 
        !            93:     /* Load XML document */
        !            94:     doc = xmlParseFile(filename);
        !            95:     if (doc == NULL) {
        !            96:        fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
        !            97:        return(-1);
        !            98:     }
        !            99: 
        !           100:     /* Create xpath evaluation context */
        !           101:     xpathCtx = xmlXPathNewContext(doc);
        !           102:     if(xpathCtx == NULL) {
        !           103:         fprintf(stderr,"Error: unable to create new XPath context\n");
        !           104:         xmlFreeDoc(doc); 
        !           105:         return(-1);
        !           106:     }
        !           107:     
        !           108:     /* Register namespaces from list (if any) */
        !           109:     if((nsList != NULL) && (register_namespaces(xpathCtx, nsList) < 0)) {
        !           110:         fprintf(stderr,"Error: failed to register namespaces list \"%s\"\n", nsList);
        !           111:         xmlXPathFreeContext(xpathCtx); 
        !           112:         xmlFreeDoc(doc); 
        !           113:         return(-1);
        !           114:     }
        !           115: 
        !           116:     /* Evaluate xpath expression */
        !           117:     xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
        !           118:     if(xpathObj == NULL) {
        !           119:         fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
        !           120:         xmlXPathFreeContext(xpathCtx); 
        !           121:         xmlFreeDoc(doc); 
        !           122:         return(-1);
        !           123:     }
        !           124: 
        !           125:     /* Print results */
        !           126:     print_xpath_nodes(xpathObj->nodesetval, stdout);
        !           127: 
        !           128:     /* Cleanup */
        !           129:     xmlXPathFreeObject(xpathObj);
        !           130:     xmlXPathFreeContext(xpathCtx); 
        !           131:     xmlFreeDoc(doc); 
        !           132:     
        !           133:     return(0);
        !           134: }
        !           135: 
        !           136: /**
        !           137:  * register_namespaces:
        !           138:  * @xpathCtx:          the pointer to an XPath context.
        !           139:  * @nsList:            the list of known namespaces in 
        !           140:  *                     "<prefix1>=<href1> <prefix2>=href2> ..." format.
        !           141:  *
        !           142:  * Registers namespaces from @nsList in @xpathCtx.
        !           143:  *
        !           144:  * Returns 0 on success and a negative value otherwise.
        !           145:  */
        !           146: int 
        !           147: register_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList) {
        !           148:     xmlChar* nsListDup;
        !           149:     xmlChar* prefix;
        !           150:     xmlChar* href;
        !           151:     xmlChar* next;
        !           152:     
        !           153:     assert(xpathCtx);
        !           154:     assert(nsList);
        !           155: 
        !           156:     nsListDup = xmlStrdup(nsList);
        !           157:     if(nsListDup == NULL) {
        !           158:        fprintf(stderr, "Error: unable to strdup namespaces list\n");
        !           159:        return(-1);     
        !           160:     }
        !           161:     
        !           162:     next = nsListDup; 
        !           163:     while(next != NULL) {
        !           164:        /* skip spaces */
        !           165:        while((*next) == ' ') next++;
        !           166:        if((*next) == '\0') break;
        !           167: 
        !           168:        /* find prefix */
        !           169:        prefix = next;
        !           170:        next = (xmlChar*)xmlStrchr(next, '=');
        !           171:        if(next == NULL) {
        !           172:            fprintf(stderr,"Error: invalid namespaces list format\n");
        !           173:            xmlFree(nsListDup);
        !           174:            return(-1); 
        !           175:        }
        !           176:        *(next++) = '\0';       
        !           177:        
        !           178:        /* find href */
        !           179:        href = next;
        !           180:        next = (xmlChar*)xmlStrchr(next, ' ');
        !           181:        if(next != NULL) {
        !           182:            *(next++) = '\0';   
        !           183:        }
        !           184: 
        !           185:        /* do register namespace */
        !           186:        if(xmlXPathRegisterNs(xpathCtx, prefix, href) != 0) {
        !           187:            fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href);
        !           188:            xmlFree(nsListDup);
        !           189:            return(-1); 
        !           190:        }
        !           191:     }
        !           192:     
        !           193:     xmlFree(nsListDup);
        !           194:     return(0);
        !           195: }
        !           196: 
        !           197: /**
        !           198:  * print_xpath_nodes:
        !           199:  * @nodes:             the nodes set.
        !           200:  * @output:            the output file handle.
        !           201:  *
        !           202:  * Prints the @nodes content to @output.
        !           203:  */
        !           204: void
        !           205: print_xpath_nodes(xmlNodeSetPtr nodes, FILE* output) {
        !           206:     xmlNodePtr cur;
        !           207:     int size;
        !           208:     int i;
        !           209:     
        !           210:     assert(output);
        !           211:     size = (nodes) ? nodes->nodeNr : 0;
        !           212:     
        !           213:     fprintf(output, "Result (%d nodes):\n", size);
        !           214:     for(i = 0; i < size; ++i) {
        !           215:        assert(nodes->nodeTab[i]);
        !           216:        
        !           217:        if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
        !           218:            xmlNsPtr ns;
        !           219:            
        !           220:            ns = (xmlNsPtr)nodes->nodeTab[i];
        !           221:            cur = (xmlNodePtr)ns->next;
        !           222:            if(cur->ns) { 
        !           223:                fprintf(output, "= namespace \"%s\"=\"%s\" for node %s:%s\n", 
        !           224:                    ns->prefix, ns->href, cur->ns->href, cur->name);
        !           225:            } else {
        !           226:                fprintf(output, "= namespace \"%s\"=\"%s\" for node %s\n", 
        !           227:                    ns->prefix, ns->href, cur->name);
        !           228:            }
        !           229:        } else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
        !           230:            cur = nodes->nodeTab[i];        
        !           231:            if(cur->ns) { 
        !           232:                fprintf(output, "= element node \"%s:%s\"\n", 
        !           233:                    cur->ns->href, cur->name);
        !           234:            } else {
        !           235:                fprintf(output, "= element node \"%s\"\n", 
        !           236:                    cur->name);
        !           237:            }
        !           238:        } else {
        !           239:            cur = nodes->nodeTab[i];    
        !           240:            fprintf(output, "= node \"%s\": type %d\n", cur->name, cur->type);
        !           241:        }
        !           242:     }
        !           243: }
        !           244: 
        !           245: #else
        !           246: int main(void) {
        !           247:     fprintf(stderr, "XPath support not compiled in\n");
        !           248:     exit(1);
        !           249: }
        !           250: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>