/*! This is the callback used by cli_setlog to print log message in CLI * param[in] s UNIX socket from backend where message should be read * param[in] arg format: txt, xml, xml2txt, xml2json */ static int cli_notification_cb(int s, void *arg) { struct clicon_msg *reply = NULL; int eof; int retval = -1; cxobj *xt = NULL; cxobj *xe; cxobj *x; enum format_enum format = (enum format_enum)arg; /* get msg (this is the reason this function is called) */ if (clicon_msg_rcv(s, &reply, &eof) < 0) goto done; if (eof){ clicon_err(OE_PROTO, ESHUTDOWN, "Socket unexpected close"); close(s); errno = ESHUTDOWN; event_unreg_fd(s, cli_notification_cb); goto done; } if (clicon_msg_decode(reply, NULL, &xt) < 0) /* XXX pass yang_spec */ goto done; if ((xe = xpath_first(xt, "//event")) != NULL){ x = NULL; while ((x = xml_child_each(xe, x, -1)) != NULL) { switch (format){ case FORMAT_XML: if (clicon_xml2file(stdout, x, 0, 1) < 0) goto done; break; case FORMAT_TEXT: if (xml2txt(stdout, x, 0) < 0) goto done; break; case FORMAT_JSON: if (xml2json(stdout, x, 1) < 0) goto done; break; default: break; } } } retval = 0; done: if (xt) xml_free(xt); if (reply) free(reply); return retval; }
static struct json_object * _xml2json(xmlNodePtr xml) { if(xml == NULL) return NULL; xmlNodePtr child; struct json_object * json = NULL; switch(xml->type) { case XML_ELEMENT_NODE: child = xml->children; if(xml->ns == NULL) { child = xml; // json_object_put(json); json = json_object_new_object(); while(child != NULL) { json_object_object_add(json, child->name, xml2json(child->children)); child = child->next; } } else if(!strcmp(xml->ns->prefix, "parsley")) { if(!strcmp(xml->name, "groups")) { // json_object_put(json); json = json_object_new_array(); while(child != NULL) { json_object_array_add(json, xml2json(child->children)); child = child->next; } } else if(!strcmp(xml->name, "group")) { // Implicitly handled by parsley:groups handler } } break; case XML_TEXT_NODE: json = json_object_new_string(xml->content); break; } return json; }