/* * Returned value should be freed with xmlFree(). */ static char *cx_get_text_node_value(xmlXPathContextPtr xpath_ctx, /* {{{ */ char *expr, const char *from_option) { xmlXPathObjectPtr values_node_obj = cx_evaluate_xpath(xpath_ctx, expr); if (values_node_obj == NULL) return NULL; /* Error already logged. */ xmlNodeSetPtr values_node = values_node_obj->nodesetval; size_t tmp_size = (values_node) ? values_node->nodeNr : 0; if (tmp_size == 0) { WARNING("curl_xml plugin: " "relative xpath expression \"%s\" from '%s' doesn't match " "any of the nodes.", expr, from_option); xmlXPathFreeObject(values_node_obj); return NULL; } if (tmp_size > 1) { WARNING("curl_xml plugin: " "relative xpath expression \"%s\" from '%s' is expected to return " "only one text node. Skipping the node.", expr, from_option); xmlXPathFreeObject(values_node_obj); return NULL; } /* ignoring the element if other than textnode/attribute*/ if (cx_if_not_text_node(values_node->nodeTab[0])) { WARNING("curl_xml plugin: " "relative xpath expression \"%s\" from '%s' is expected to return " "only text/attribute node which is not the case. " "Skipping the node.", expr, from_option); xmlXPathFreeObject(values_node_obj); return NULL; } char *node_value = (char *)xmlNodeGetContent(values_node->nodeTab[0]); /* free up object */ xmlXPathFreeObject(values_node_obj); return node_value; } /* }}} char * cx_get_text_node_value */
static int cx_handle_instance_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ cx_xpath_t *xpath, value_list_t *vl, _Bool is_table) { xmlXPathObjectPtr instance_node_obj = NULL; xmlNodeSetPtr instance_node = NULL; memset (vl->type_instance, 0, sizeof (vl->type_instance)); /* If the base xpath returns more than one block, the result is assumed to be * a table. The `Instance' option is not optional in this case. Check for the * condition and inform the user. */ if (is_table && (xpath->instance == NULL)) { WARNING ("curl_xml plugin: " "Base-XPath %s is a table (more than one result was returned), " "but no instance-XPath has been defined.", xpath->path); return (-1); } /* instance has to be an xpath expression */ if (xpath->instance != NULL) { int tmp_size; instance_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->instance); if (instance_node_obj == NULL) return (-1); /* error is logged already */ instance_node = instance_node_obj->nodesetval; tmp_size = (instance_node) ? instance_node->nodeNr : 0; if (tmp_size <= 0) { WARNING ("curl_xml plugin: " "relative xpath expression for 'InstanceFrom' \"%s\" doesn't match " "any of the nodes. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } if (tmp_size > 1) { WARNING ("curl_xml plugin: " "relative xpath expression for 'InstanceFrom' \"%s\" is expected " "to return only one text node. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } /* ignoring the element if other than textnode/attribute */ if (cx_if_not_text_node(instance_node->nodeTab[0])) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" is expected to return only text node " "which is not the case. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } } /* if (xpath->instance != NULL) */ if (xpath->instance_prefix != NULL) { if (instance_node != NULL) { char *node_value = (char *) xmlNodeGetContent(instance_node->nodeTab[0]); ssnprintf (vl->type_instance, sizeof (vl->type_instance),"%s%s", xpath->instance_prefix, node_value); sfree (node_value); } else sstrncpy (vl->type_instance, xpath->instance_prefix, sizeof (vl->type_instance)); } else { /* If instance_prefix and instance_node are NULL, then * don't set the type_instance */ if (instance_node != NULL) { char *node_value = (char *) xmlNodeGetContent(instance_node->nodeTab[0]); sstrncpy (vl->type_instance, node_value, sizeof (vl->type_instance)); sfree (node_value); } } /* Free `instance_node_obj' this late, because `instance_node' points to * somewhere inside this structure. */ xmlXPathFreeObject (instance_node_obj); return (0); } /* }}} int cx_handle_instance_xpath */
static int cx_handle_single_value_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ cx_xpath_t *xpath, const data_set_t *ds, value_list_t *vl, int index) { xmlXPathObjectPtr values_node_obj; xmlNodeSetPtr values_node; int tmp_size; char *node_value; values_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->values[index].path); if (values_node_obj == NULL) return (-1); /* Error already logged. */ values_node = values_node_obj->nodesetval; tmp_size = (values_node) ? values_node->nodeNr : 0; if (tmp_size == 0) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" doesn't match any of the nodes. " "Skipping...", xpath->values[index].path); xmlXPathFreeObject (values_node_obj); return (-1); } if (tmp_size > 1) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" is expected to return " "only one node. Skipping...", xpath->values[index].path); xmlXPathFreeObject (values_node_obj); return (-1); } /* ignoring the element if other than textnode/attribute*/ if (cx_if_not_text_node(values_node->nodeTab[0])) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" is expected to return " "only text/attribute node which is not the case. Skipping...", xpath->values[index].path); xmlXPathFreeObject (values_node_obj); return (-1); } node_value = (char *) xmlNodeGetContent(values_node->nodeTab[0]); switch (ds->ds[index].type) { case DS_TYPE_COUNTER: vl->values[index].counter = (counter_t) strtoull (node_value, /* endptr = */ NULL, /* base = */ 0); break; case DS_TYPE_DERIVE: vl->values[index].derive = (derive_t) strtoll (node_value, /* endptr = */ NULL, /* base = */ 0); break; case DS_TYPE_ABSOLUTE: vl->values[index].absolute = (absolute_t) strtoull (node_value, /* endptr = */ NULL, /* base = */ 0); break; case DS_TYPE_GAUGE: vl->values[index].gauge = (gauge_t) strtod (node_value, /* endptr = */ NULL); } /* free up object */ xmlXPathFreeObject (values_node_obj); sfree (node_value); /* We have reached here which means that * we have got something to work */ return (0); } /* }}} int cx_handle_single_value_xpath */