From 86a62889d249f395d2d9d412159015c333f7cfa8 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Wed, 27 Jun 2018 10:00:21 +0000 Subject: [PATCH] Feature: Added a way to find a node by attribute (useful for IDs). --- src/reportxml.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/reportxml.h | 2 ++ 2 files changed, 44 insertions(+) diff --git a/src/reportxml.c b/src/reportxml.c index 21a4e94b..b175b98b 100644 --- a/src/reportxml.c +++ b/src/reportxml.c @@ -217,6 +217,14 @@ reportxml_node_t * reportxml_get_root_node(reportxml_t *report) return report->root; } +reportxml_node_t * reportxml_get_node_by_attribute(reportxml_t *report, const char *key, const char *value, int include_definitions) +{ + if (!report || !key || !value) + return NULL; + + return reportxml_node_get_child_by_attribute(report->root, key, value, include_definitions); +} + reportxml_t * reportxml_parse_xmldoc(xmlDocPtr doc) { reportxml_node_t *root; @@ -652,6 +660,40 @@ reportxml_node_t * reportxml_node_get_child(reportxml_node_t *node, size_t return node->childs[idx]; } +reportxml_node_t * reportxml_node_get_child_by_attribute(reportxml_node_t *node, const char *key, const char *value, int include_definitions) +{ + reportxml_node_t *ret; + xmlChar *k; + size_t i; + + if (!node || !key ||!value) + return NULL; + + k = xmlGetProp(node->xmlnode, XMLSTR(key)); + if (k != NULL) { + if (strcmp((const char*)k, value) == 0) { + xmlFree(k); + + if (refobject_ref(node) != 0) + return NULL; + + return node; + } + xmlFree(k); + } + + if (node->type == REPORTXML_NODE_TYPE_DEFINITION && !include_definitions) + return NULL; + + for (i = 0; i < node->childs_len; i++) { + ret = reportxml_node_get_child_by_attribute(node->childs[i], key, value, include_definitions); + if (ret != NULL) + return ret; + } + + return NULL; +} + int reportxml_node_set_content(reportxml_node_t *node, const char *value) { const struct nodedef *nodedef; diff --git a/src/reportxml.h b/src/reportxml.h index 18713fd0..950db43b 100644 --- a/src/reportxml.h +++ b/src/reportxml.h @@ -36,6 +36,7 @@ typedef enum { reportxml_t * reportxml_new(void); reportxml_node_t * reportxml_get_root_node(reportxml_t *report); +reportxml_node_t * reportxml_get_node_by_attribute(reportxml_t *report, const char *key, const char *value, int include_definitions); reportxml_t * reportxml_parse_xmldoc(xmlDocPtr doc); xmlDocPtr reportxml_render_xmldoc(reportxml_t *report); @@ -49,6 +50,7 @@ char * reportxml_node_get_attribute(reportxml_node_t *node, con int reportxml_node_add_child(reportxml_node_t *node, reportxml_node_t *child); ssize_t reportxml_node_count_child(reportxml_node_t *node); reportxml_node_t * reportxml_node_get_child(reportxml_node_t *node, size_t idx); +reportxml_node_t * reportxml_node_get_child_by_attribute(reportxml_node_t *node, const char *key, const char *value, int include_definitions); int reportxml_node_set_content(reportxml_node_t *node, const char *value); char * reportxml_node_get_content(reportxml_node_t *node);