[collectd] [PATCH] Add support to aggregated value obtained by xpath functions
Antoine Monnet
tonio+progs at xmon.net
Fri Nov 30 11:18:18 CET 2012
Hi,
This patch adds support to aggregated value obtained by xpath functions.
Ex:
expression "count(//client)"
returns the number of "client" node in the document
Thanks,
Antoine
---
src/curl_xml.c | 130 +++++++++++++++++++++++++++++++++++---------------------
1 file changed, 81 insertions(+), 49 deletions(-)
diff --git a/src/curl_xml.c b/src/curl_xml.c
index 46e0d49..4248751 100644
--- a/src/curl_xml.c
+++ b/src/curl_xml.c
@@ -237,69 +237,101 @@ 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;
+ xmlXPathObjectPtr values_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)
+ values_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->values[index].path);
+ if (values_obj == NULL)
return (-1); /* Error already logged. */
- values_node = values_node_obj->nodesetval;
- tmp_size = (values_node) ? values_node->nodeNr : 0;
+ switch (values_obj->type) {
+
+ case XPATH_NODESET:
+ values_node = values_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_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_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_obj);
+ return (-1);
+ }
+ node_value = (char *) xmlNodeGetContent(values_node->nodeTab[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);
- }
+ case XPATH_STRING:
+ if (values_obj->type == XPATH_STRING)
+ node_value = (char *)values_obj->stringval;
- 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);
- }
+ 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);
+ }
+ break;
- /* ignoring the element if other than textnode/attribute*/
- if (cx_if_not_text_node(values_node->nodeTab[0]))
- {
+ case XPATH_NUMBER:
+ switch (ds->ds[index].type)
+ {
+ case DS_TYPE_COUNTER:
+ vl->values[index].counter = (counter_t) values_obj->floatval;
+ break;
+ case DS_TYPE_DERIVE:
+ vl->values[index].derive = (derive_t) values_obj->floatval;
+ break;
+ case DS_TYPE_ABSOLUTE:
+ vl->values[index].absolute = (absolute_t) values_obj->floatval;
+ break;
+ case DS_TYPE_GAUGE:
+ vl->values[index].gauge = (gauge_t) values_obj->floatval;
+ }
+ break;
+ default:
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);
+ "relative xpath expression \"%s\" result not handled. "
+ "Skipping...", xpath->values[index].path);
+ xmlXPathFreeObject (values_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);
+ xmlXPathFreeObject (values_obj);
/* We have reached here which means that
* we have got something to work */
--
1.7.10.4
More information about the collectd
mailing list