Search code examples
cxml-parsinglibxml2

Libxml issue to get the attribute of a tag


I want to get only the value of attribut Object but if don't work after the first node because it don't enter in the loop, why ?

This is my xml file:

     <msg><tag date="1557417027960" session="1697"><decision object="BAST04HEF" reliability="95" context="RO" x="796" y="371" 
 width="89" height="18" 
 direction="front"><jpeg></jpeg></decision></tag></msg>

And this my code:

int main(int argc, char **argv) {

  char         *docname;
  xmlDocPtr    doc;
  xmlNodePtr   cur;
  xmlChar      *object;

  if (argc < 2) {
    printf("Commande: %s nom_du_fichier\n", argv[0]);
    return EXIT_FAILURE;
  }


  docname = argv[1];

  doc = xmlParseFile(docname);
  cur = xmlDocGetRootElement(doc);

  cur = cur->xmlChildrenNode;
  while (cur != NULL) {
      if ((!xmlStrcmp(cur->name, (const xmlChar *)"decision"))) {
        object = xmlGetProp(cur, "object");
        printf("object: %s\n", object);
        xmlFree(object);
      }
      cur = cur->next;
  }
  xmlFreeDoc(doc);
  return EXIT_SUCCESS;
}

Solution

  • Your code processes only one level children, i.e. the direct children of the root element.

    cur = xmlDocGetRootElement(doc); gets the root element.

    cur = cur->xmlChildrenNode; gets the first (direct) child of the root element.

    In you loop you get all siblings of this first child with cur = cur->next;, but you don't process their possible children.

    Your XML snippet shows that you have at least three layers: msg - tag - decision.

    If you want to process all decision elements regardless of what their parents are, you could use a recursive function.

    static void processChildren(xmlNodePtr cur)
    
    int main(int argc, char **argv) {
    
      char         *docname;
      xmlDocPtr    doc;
      xmlNodePtr   cur;
      xmlChar      *object;
    
      if (argc < 2) {
        printf("Commande: %s nom_du_fichier\n", argv[0]);
        return EXIT_FAILURE;
      }
    
    
      docname = argv[1];
    
      doc = xmlParseFile(docname);
      cur = xmlDocGetRootElement(doc);
    
      processChildren(cur->xmlChildrenNode);
    
      xmlFreeDoc(doc);
      return EXIT_SUCCESS;
    }
    
    static void processChildren(xmlNodePtr cur)
    {
        while (cur != NULL) {
            if ((!xmlStrcmp(cur->name, (const xmlChar *)"decision"))) {
                object = xmlGetProp(cur, "object");
                printf("object: %s\n", object);
                xmlFree(object);
            }
            else
            {
                processChildren(cur->children);
            }
            cur = cur->next;
        }
    }