Проблема с libxml для получения атрибута тега - PullRequest
2 голосов
/ 10 мая 2019

Я хочу получить только значение атрибута Object, но если после первого узла он не работает, потому что он не входит в цикл, почему?

Это мой XML-файл:

     <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>

А это мой код:

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;
}

1 Ответ

2 голосов
/ 10 мая 2019

Ваш код обрабатывает только один дочерний уровень, то есть прямые дочерние элементы корневого элемента.

cur = xmlDocGetRootElement(doc); получает корневой элемент.

cur = cur->xmlChildrenNode; получает первый (прямой) дочерний элементкорневого элемента.

В цикле вы получаете всех братьев и сестер этого первого потомка с cur = cur->next;, но вы не обрабатываете их возможных потомков.

Ваш фрагмент XML показывает, что у вас естьпо крайней мере, три слоя: msg - tag - decision.

Если вы хотите обработать все элементы decision независимо от их родителей, вы можете использовать рекурсивную функцию.

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;
    }
}
...