Skip to content

Instantly share code, notes, and snippets.

@lexborisov
Created October 19, 2021 10:26
Show Gist options
  • Save lexborisov/e9c4215062109fbc728a03029d41cd5d to your computer and use it in GitHub Desktop.
Save lexborisov/e9c4215062109fbc728a03029d41cd5d to your computer and use it in GitHub Desktop.
#include <lexbor/html/html.h>
#include <lexbor/css/css.h>
#include <lexbor/selectors/selectors.h>
lxb_status_t
callback(const lxb_char_t *data, size_t len, void *ctx)
{
printf("%.*s", (int) len, (const char *) data);
return LXB_STATUS_OK;
}
lxb_status_t
find_callback(lxb_dom_node_t *node, lxb_css_selector_specificity_t *spec,
void *ctx)
{
return lxb_html_serialize_deep_cb(node, callback, NULL);
}
int main(void) {
lxb_status_t status;
lxb_dom_node_t *body;
lxb_html_document_t *document;
lxb_css_parser_t *parser;
lxb_selectors_t *selectors;
lxb_css_selector_list_t *list;
static const lxb_char_t html[] = "<table><tr>\n"
"<th headers=\"1.h.1.1\" id=\"press1.r.1.1.1\"><p class=\"sub2\">Food at home</p></th>\n"
"<td headers=\"1.h.1.2\"><span class=\"datavalue\">7.652</span></td>\n"
"<td headers=\"1.h.1.3 press1.h.2.3\"><span class=\"datavalue\">251.369</span></td>\n"
"<td headers=\"1.h.1.3 press1.h.2.4\"><span class=\"datavalue\">259.825</span></td>\n"
"<td headers=\"1.h.1.3 press1.h.2.5\"><span class=\"datavalue\">262.695</span></td>\n"
"<td headers=\"1.h.1.6 press1.h.2.6\"><span class=\"datavalue\">4.5</span></td>\n"
"<td headers=\"1.h.1.6 press1.h.2.7\"><span class=\"datavalue\">1.1</span></td>\n"
"<td headers=\"1.h.1.8 press1.h.2.8\"><span class=\"datavalue\">0.7</span></td>\n"
"<td headers=\"1.h.1.8 press1.h.2.9\"><span class=\"datavalue\">0.4</span></td>\n"
"<td headers=\"1.h.1.8 press1.h.2.10\"><span class=\"datavalue\">1.2</span></td>\n"
"</tr></table>";
static const lxb_char_t slctrs[] = "tr > td[headers = '1.h.1.8 press1.h.2.10'] > .datavalue";
/*
* OR
* static const lxb_char_t slctrs[] = "tr > td:last-child .datavalue";
* OR
* static const lxb_char_t slctrs[] = "tr td[headers *= 'press1.h.2.10'] span.datavalue";
* OR
* ...
*/
document = lxb_html_document_create();
if (document == NULL) {
return EXIT_FAILURE;
}
status = lxb_html_document_parse(document, html, sizeof(html) - 1);
if (status != LXB_STATUS_OK) {
return EXIT_FAILURE;
}
/* Create CSS parser. */
parser = lxb_css_parser_create();
status = lxb_css_parser_init(parser, NULL, NULL);
if (status != LXB_STATUS_OK) {
return EXIT_FAILURE;
}
/* Selectors. */
selectors = lxb_selectors_create();
status = lxb_selectors_init(selectors);
if (status != LXB_STATUS_OK) {
return EXIT_FAILURE;
}
list = lxb_css_selectors_parse(parser, slctrs, sizeof(slctrs) - 1);
if (parser->status != LXB_STATUS_OK) {
return EXIT_FAILURE;
}
/* Find DOM/HTML nodes by selectors. */
body = lxb_dom_interface_node(lxb_html_document_body_element(document));
if (body == NULL) {
return EXIT_FAILURE;
}
// lxb_html_serialize_deep_cb(body, callback, NULL);
status = lxb_selectors_find(selectors, body, list, find_callback, NULL);
if (status != LXB_STATUS_OK) {
return EXIT_FAILURE;
}
printf("\n");
/* Destroy Selectors object. */
(void) lxb_selectors_destroy(selectors, true);
/* Destroy resources for CSS Parser. */
(void) lxb_css_parser_destroy(parser, true);
/* Destroy all Selector List memory. */
lxb_css_selector_list_destroy_memory(list);
/* Destroy HTML Document. */
lxb_html_document_destroy(document);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment