Subversion Repositories f9daq

Rev

Rev 1 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*  

xpath2 ini/config.xml '//anode'
 
 * section:     XPath
 * synopsis:    Load a document, locate subelements with XPath,
 * usage:       xpath2 <xml-file> <xpath-expr>
 * test:        xpath2 test3.xml '//discarded'
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <vector>

#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>

#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_SAX1_ENABLED) && \
    defined(LIBXML_OUTPUT_ENABLED)




static int  getvalue(xmlXPathContextPtr xpathCtx, const xmlChar * xpathExpr, std::vector <xmlChar *> &retval);
static xmlChar * getvalue(xmlXPathContextPtr xpathCtx, const xmlChar * xpathExpr, int which=0);


int
main(int argc, char **argv) {
    std::vector<xmlChar *> retval;
    xmlDocPtr doc;
    xmlXPathContextPtr xpathCtx;
    int size;
   
    xmlInitParser();
    LIBXML_TEST_VERSION
   
     /* Load XML document */
    doc = xmlParseFile(argv[1]);
    if (doc == NULL) {
        fprintf(stderr, "Error: unable to parse file \"%s\"\n", argv[1]);
        return(-1);
    }

    /* Create xpath evaluation context */
    xpathCtx = xmlXPathNewContext(doc);
    if(xpathCtx == NULL) {
        fprintf(stderr,"Error: unable to create new XPath context\n");
        xmlFreeDoc(doc);
        return(-1);
    }
   
    for (int i=2; i<argc;i++){    
      size = getvalue(xpathCtx, BAD_CAST argv[i] , retval);
      printf ("-->size = %d value %s\n",size, getvalue(xpathCtx, BAD_CAST argv[i])   );
    }
     
    xmlXPathFreeContext(xpathCtx);
    xmlFreeDoc(doc);    
    xmlCleanupParser();
    xmlMemoryDump();
    return 0;
}


/**
 * getvalue:
 * @xpathCtx:           the input xmlXPathContextPtr
 * @xpathExpr:          the xpath expression for evaluation.
 *
 * evaluates XPath expression
 *
 * Returns node content
 */

int getvalue(xmlXPathContextPtr xpathCtx, const xmlChar* xpathExpr, std::vector<xmlChar *> &retval) {
   
    xmlXPathObjectPtr xpathObj;
    xmlNodeSetPtr nodes;
    xmlChar * ret=NULL;
    int size;
    int i;
    assert(xpathExpr);
    /* Evaluate xpath expression */
    xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
    if(xpathObj == NULL) {
        fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
        return retval.size();
    }
   
    nodes  = xpathObj->nodesetval;
    size   = (nodes) ? nodes->nodeNr : 0;
    for(i = 0; i< size; i++) {
      ret = xmlNodeGetContent(nodes->nodeTab[i]);
      if(ret) {
        retval.push_back(ret);
        printf("[%d] %s         Return value: %s\n", i, xpathExpr, ret);
      }  
    }
   
    /* Cleanup of XPath data */
    xmlXPathFreeObject(xpathObj);
   
    return retval.size();
}

xmlChar *  getvalue(xmlXPathContextPtr xpathCtx, const xmlChar* xpathExpr, int which) {
   
    xmlXPathObjectPtr xpathObj;
    xmlNodeSetPtr nodes;
    xmlChar * ret=NULL;
    int size;
    int i;
    assert(xpathExpr);
    /* Evaluate xpath expression */
    xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
    if(xpathObj == NULL) {
        fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
        return NULL;
    }
   
    nodes  = xpathObj->nodesetval;
    size   = (nodes) ? nodes->nodeNr : 0;
    for(i = 0; i< size; i++) {
      ret = xmlNodeGetContent(nodes->nodeTab[i]);
      if(ret) {  
        printf("%s         Return value: %s\n",  xpathExpr, ret);
        return ret;
      }  
    }
   
    /* Cleanup of XPath data */
    xmlXPathFreeObject(xpathObj);
   
    return NULL;
}

#endif