#include "rapidxml.hpp" #include inline bool is_content_root(const char* name, std::size_t len) { return (len == 8 && std::memcmp(name, "abstract", 8) == 0) || (len == 4 && std::memcmp(name, "body", 4) == 0); } size_t sum_text(const rapidxml::xml_node<>* node) { size_t total = 0; for (auto* child = node->first_node(); child; child = child->next_sibling()) { if (child->type() == rapidxml::node_type::node_data) { total += child->value_size(); } else if (child->type() == rapidxml::node_type::node_element) { total += sum_text(child); } } return total; } size_t walk(const rapidxml::xml_node<>* node) { size_t total = 0; for (auto* child = node->first_node(); child; child = child->next_sibling()) { if (child->type() != rapidxml::node_type::node_element) continue; if (is_content_root(child->name(), child->name_size())) { total += sum_text(child); } else { total += walk(child); } } return total; } size_t pubmed_len(char* buffer, size_t /*len*/) { rapidxml::xml_document<> doc; doc.parse(buffer); return walk(&doc); } size_t pubmed_len_with_entities(char* buffer, size_t /*len*/) { rapidxml::xml_document<> doc; doc.parse(buffer); return walk(&doc); }