aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/quickmedia/HtmlSearch.h8
-rw-r--r--src/HtmlSearch.c31
2 files changed, 39 insertions, 0 deletions
diff --git a/include/quickmedia/HtmlSearch.h b/include/quickmedia/HtmlSearch.h
index e2b0ecc..8ce7ff4 100644
--- a/include/quickmedia/HtmlSearch.h
+++ b/include/quickmedia/HtmlSearch.h
@@ -58,6 +58,14 @@ typedef struct {
QuickMediaStringView quickmedia_html_node_get_attribute_value(QuickMediaHtmlNode *self, const char *attribute_name);
/*
+ Returns NULL if not found.
+ The result is only valid within the callback function scope.
+ This function is not recursive.
+ Case insensitive search.
+*/
+QuickMediaHtmlNode* quickmedia_html_node_find_child(QuickMediaHtmlNode *self, const char *tag_name, const char *attribute_name, const char *attribute_value);
+
+/*
Returns an empty string if the node doesn't have any text or if there was an error creating the text.
The result is only valid within the callback function scope.
The result is stripped of whitespace on the left and right side.
diff --git a/src/HtmlSearch.c b/src/HtmlSearch.c
index 8449ac9..adf64bd 100644
--- a/src/HtmlSearch.c
+++ b/src/HtmlSearch.c
@@ -450,6 +450,37 @@ QuickMediaStringView quickmedia_html_node_get_attribute_value(QuickMediaHtmlNode
}
}
+QuickMediaHtmlNode* quickmedia_html_node_find_child(QuickMediaHtmlNode *self, const char *tag_name, const char *attribute_name, const char *attribute_value) {
+ QuickMediaStringView tag;
+ tag.data = tag_name;
+ tag.size = strlen(tag_name);
+
+ QuickMediaStringView attr_name;
+ attr_name.data = attribute_name;
+ attr_name.size = strlen(attribute_name);
+
+ QuickMediaStringView attr_value;
+ attr_value.data = attribute_value;
+ attr_value.size = strlen(attribute_value);
+
+ for(QuickMediaHtmlChildNode *child = self->first_child; child; child = child->next) {
+ if(!child->node.is_tag)
+ continue;
+
+ if(!string_views_equal_case_insensitive(child->node.name, tag))
+ continue;
+
+ QuickMediaHtmlAttribute *attr = get_attribute_by_name(child, attr_name);
+ if(!attr)
+ continue;
+
+ if(string_views_equal_case_insensitive(attr->value, attr_value))
+ return &child->node;
+ }
+
+ return NULL;
+}
+
static int merge_inner_text(QuickMediaHtmlNode *node, QuickMediaString *str) {
if(node->is_tag) {
int newline = 0;