aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2023-08-01 16:56:40 +0200
committerdec05eba <dec05eba@protonmail.com>2023-08-01 16:56:40 +0200
commit0eb546dfc74080e4cd00772dafb0aa2a46bc4153 (patch)
tree4fe54e325f35fe6c1b77e8548a7ce1ea16f485ef
parent3e01d0dc158358d091bdee0ddf90b0f0562e1c89 (diff)
Add quickmedia_html_node_find_child
-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;