Make html parser use case insensitive unordered_map for attributes

This commit is contained in:
2026-09-25 16:17:11 -05:00
parent 95442f8acc
commit 15f08f474f
6 changed files with 37 additions and 21 deletions
+3 -7
View File
@@ -9,14 +9,10 @@ Json::JToken Html2JToken(std::shared_ptr<Html::HtmlNode> node) {
} else { } else {
Json::JObject obj; Json::JObject obj;
obj.SetValue("Tag", node->text_or_tag); obj.SetValue("Tag", node->text_or_tag);
Json::JArray attrs; Json::JObject attrs;
for (auto &item : node->attributes) { for (auto &item : node->attributes) {
if (item.second) attrs.SetValue(item.first,
attrs.Add(Json::JObject( item.second.value_or<Json::JToken>(nullptr));
{{"Key", item.first}, {"Value", item.second.value()}}));
else
attrs.Add(
Json::JObject({{"Key", item.first}, {"Value", nullptr}}));
} }
obj.SetValue("Attributes", attrs); obj.SetValue("Attributes", attrs);
+7 -7
View File
@@ -58,13 +58,13 @@ int main(int argc, char **argv) {
html->FindNodes("meta", metaTags); html->FindNodes("meta", metaTags);
for (auto &meta : metaTags) { for (auto &meta : metaTags) {
std::optional<std::string> prop, content; auto prop_off = meta->attributes.find("property");
for (auto &[k, v] : meta->attributes) { auto content_off = meta->attributes.find("content");
if (k == "property" && v) if (!(prop_off != meta->attributes.end() &&
prop = *v; content_off != meta->attributes.end()))
if (k == "content" && v) continue;
content = *v; auto &prop = prop_off->second;
} auto &content = content_off->second;
if (prop && content && prop->find("og:") == 0) { if (prop && content && prop->find("og:") == 0) {
Tesses::Framework::Console::WriteView(prop.value()); Tesses::Framework::Console::WriteView(prop.value());
+3
View File
@@ -1,5 +1,8 @@
# Changelog # Changelog
## 0.0.9
Make html parser use case insensitive unordered_map for attributes
## 0.0.8 ## 0.0.8
Fixed a stoll bug that was there since day one, html parser, fix pkgconfig Fixed a stoll bug that was there since day one, html parser, fix pkgconfig
+1 -1
View File
@@ -1,3 +1,3 @@
set(TESSESFRAMEWORK_MAJOR_VERSION 0) set(TESSESFRAMEWORK_MAJOR_VERSION 0)
set(TESSESFRAMEWORK_MINOR_VERSION 0) set(TESSESFRAMEWORK_MINOR_VERSION 0)
set(TESSESFRAMEWORK_PATCH_VERSION 8) set(TESSESFRAMEWORK_PATCH_VERSION 9)
+19 -1
View File
@@ -21,13 +21,31 @@
#pragma once #pragma once
#include "../TextStreams/TextReader.hpp" #include "../TextStreams/TextReader.hpp"
#include <algorithm>
namespace Tesses::Framework::Serialization::Html { namespace Tesses::Framework::Serialization::Html {
struct CaseInsensitiveHash {
size_t operator()(const std::string &s) const {
std::string lower = s;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return std::hash<std::string>{}(lower);
}
};
struct CaseInsensitiveEqual {
bool operator()(const std::string &a, const std::string &b) const {
return strcasecmp(a.c_str(), b.c_str()) == 0;
}
};
struct HtmlNode; struct HtmlNode;
struct HtmlNode : public std::enable_shared_from_this<HtmlNode> { struct HtmlNode : public std::enable_shared_from_this<HtmlNode> {
std::string text_or_tag; std::string text_or_tag;
std::vector<std::pair<std::string, std::optional<std::string>>> attributes; std::unordered_map<std::string, std::optional<std::string>,
CaseInsensitiveHash, CaseInsensitiveEqual>
attributes;
std::vector<std::shared_ptr<HtmlNode>> children; std::vector<std::shared_ptr<HtmlNode>> children;
bool isText = false; bool isText = false;
+4 -5
View File
@@ -360,16 +360,15 @@ struct HtmlParser {
if (v.type == if (v.type ==
HtmlLexTokenType::STRING) { HtmlLexTokenType::STRING) {
Read(); Read();
newNode->attributes.emplace_back( newNode->attributes[k.text] =
k.text,
Http::HttpUtils::HtmlDecode( Http::HttpUtils::HtmlDecode(
v.text)); v.text);
continue; continue;
} }
} }
} }
newNode->attributes.emplace_back(k.text, newNode->attributes[k.text] = std::nullopt;
std::nullopt);
continue; continue;
} }