Search code examples
cxmlparsingdoc

Get IP from .xml doc In C Program


Im doing a program in C and i want to get two IPs from this .xml doc.

enter image description here

I was doing this way but its returning only the first IP:

void parseGlobalStats(xmlDocPtr doc, xmlNodePtr cur) {

xmlChar *IP;

    cur = cur->xmlChildrenNode;
    cur = cur->next;
    cur = cur->xmlChildrenNode;
   while (cur != NULL)
{
     if ((!xmlStrcmp(cur->name, (const xmlChar *)"IP")))
     {
     IP = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
     printf("IP = %s\n",IP);
     }
     return;
}
}

It is compiling well but it is returning only the first IP(179.199.24.207) when executed. How can i create a function that get 2 IPs from this doc and store it in a string variable?


Solution

  • Since you are only looking for some global stats (including IP), you can use xpath evaluation.

    Using xpath, the following file [ test.xml ]:

    <icestats>
      <source mount="/stream">
        <Listeners>2</Listeners>
        <listener>
          <IP>179.199.24.207</IP>
          <UserAgent>cmus/v2.4.3</UserAgent>
          <Connected>76810</Connected>
          <ID>405</ID>
        </listener>
        <listener>
          <IP>177.133.209.80</IP>
          <UserAgent>WinampMPEG/5.0</UserAgent>
          <Connected>72</Connected>
          <ID>1435</ID>
        </listener>
      </source>
    </icestats>
    

    can extract IP with [ test.c ]:

    /* refactored [minimal changes] from libxml2 tutorials
     * [ http://www.xmlsoft.org/tutorial/apd.html ]
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <libxml/parser.h>
    #include <libxml/xpath.h>
    
    xmlDocPtr getdoc (char *docname) 
    {
      xmlDocPtr doc;
      doc = xmlParseFile(docname);
    
      if (doc == NULL ) {
        fprintf(stderr,"Document not parsed successfully. \n");
        return NULL;
      }
    
      return doc;
    }
    
    xmlXPathObjectPtr getnodeset (xmlDocPtr doc, xmlChar *xpath)
    {
      xmlXPathContextPtr context;
      xmlXPathObjectPtr result;
    
      context = xmlXPathNewContext(doc);
      if (context == NULL) {
        printf("Error in xmlXPathNewContext\n");
        return NULL;
      }
      result = xmlXPathEvalExpression(xpath, context);
      xmlXPathFreeContext(context);
      if (result == NULL) {
        printf("Error in xmlXPathEvalExpression\n");
        return NULL;
      }
      if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
        xmlXPathFreeObject(result);
        printf("No result\n");
        return NULL;
      }
      return result;
    }
    
    int main(int argc, char **argv) 
    {
      char *docname = "test.xml";
      xmlDocPtr doc;
      xmlChar *xpath = (xmlChar*) "//IP";
      xmlNodeSetPtr nodeset;
      xmlXPathObjectPtr result;
      int i;
      xmlChar *IP;
    
      doc = getdoc(docname);
      result = getnodeset (doc, xpath);
      if (result) 
      {
        nodeset = result->nodesetval;
        for (i=0; i < nodeset->nodeNr; i++) 
        {
          IP = xmlNodeListGetString(
              doc, 
              nodeset->nodeTab[i]->xmlChildrenNode, 
              1);
          printf("IP: %s\n", IP);
          xmlFree(IP);
        }
        xmlXPathFreeObject (result);
      }
      xmlFreeDoc(doc);
      xmlCleanupParser();
      return (1);
    }
    

    sample output:

    ./test 
    IP: 179.199.24.207
    IP: 177.133.209.80
    

    Further reference