cpphtmlbuilder-c++灵活构造html

引言

HtmlRender - c++实现的html生成类一文中,我提到为了用c++实现TinML转html,自行构建了一个简易html编辑类。现在,我将其单独分离出来进行维护,并做了很多改进。

项目地址:cppHtmlBuilder-Gitee

特性概要

  • 自由指定html标签名称、参数、参数值
  • 动态添加或修改标签参数-值、内容
  • 动态添加、修改、删除子元素
  • 随时生成html文本
  • 可获取亲元素、所有子元素

以上特性借鉴了python-dominate和rust-build_html

HtmlElement

HtmlElement是唯一类,用来动态构建html。允许三种初始化:

cpp 复制代码
HtmlElement()=default;

HtmlElement(std::string tag, std::string content="", bool onetag=false, bool pre=false){
    // tag     标签
    // content 内容
    // onetag  是否为单标签
    // pre     是否直接写入内容而不用转义
}

HtmlElement(std::string tag, std::string content, std::map<std::string,std::string> kws, bool onetag=false, bool pre=false){
    // kws 参数名-值,...
}

由于内部操作所有元素实例均以指针形式存在。所有元素尽可能创建在堆上,每个元素销毁时会自动销毁下辖所有元素。

输出字符串

cpp 复制代码
std::string HtmlElement::render(std::string split_s="\n");
// split_s 间隔文本

该方法将本标签的当前状态输出为字符串,例如:

cpp 复制代码
HtmlElement html = HtmlElement{"html"};
html.add(new HtmlElement{"div"});
cout << html.render() << endl;
/*
<html>
<div></div>
</html>
*/

添加子元素

有两种方法添加子元素:直接添加和链式添加。

直接添加

cpp 复制代码
void HtmlElement::add(HtmlElement* item);

链式添加

cpp 复制代码
HtmlElement* HtmlElement::add_with(HtmlElement* item);
// return this

使用add_with会返回自身指针,因此可用于链式添加,例如:

cpp 复制代码
HtmlElement root = {"html"};
root.add((new HtmlElement{"head"})
         ->add_with(new HtmlElement{"title", "My Page"})
         ->add_with(new HtmlElement{"meta"})
         ->add_with(new HtmlElement{"meta"}));
cout << root.render() << endl;
/*
<html>
<head>
<title>My Page</title>
<meta></meta>
<meta></meta>
</head>
</html>
*/

该功能借鉴rust-build_html

设置内容

cpp 复制代码
void HtmlElement::configcnt(std::string content);

设置所有参数

cpp 复制代码
void HtmlElement::configkws(std::map<std::string, std::string> kws);

获取亲标签

cpp 复制代码
HtmlElement* HtmlElement::parent();

获取所有子元素

cpp 复制代码
std::list<HtmlElement*>& HtmlElement::children()

示例

cpp 复制代码
#include <iostream>
#include <htmlbuilder.hpp>

using namespace std;

int main() {
    HtmlElement root = {"html"};
    root.add((new HtmlElement{"head"})->add_with(new HtmlElement{"title", "My Page"}));
    HtmlElement* body = new HtmlElement{"body"};
    root.add(body);

    HtmlElement* div = new HtmlElement{"div"};
    body->add(div);
    div->configkws({{"id", "main"}, {"class", "container<>"}});
    div->configcnt("&<html><div>content内容&");

    div->add(new HtmlElement{"h1", "cpphtmlbuilder"});

    // 添加列表
    HtmlElement* ul = new HtmlElement{"ul"};
    div->add(ul);
    for (int i = 0; i < 10; i++) {
        ul->add(new HtmlElement{"li", to_string(i)});
    }
    // 删除倒数第二个li
    {
        auto it = prev(ul->children().end(), 2);
        auto element = *it;
        ul->children().erase(it);
        delete element;// 仍在堆上,需要手动释放
    }

    div->add(new HtmlElement{"", "content内容,只要标签名为空即可"});

    auto result = root.render();
    cout << result << endl;
}

输出内容:

html 复制代码
<html>
<head>
<title>My Page</title>
</head>
<body>
<div class="container&lt;&gt;" id="main">&amp;&lt;html&gt;&lt;div&gt;content内容&amp;
<h1>cpphtmlbuilder</h1>
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>9</li>
</ul>
content内容,只要标签名为空即可
</div>
</body>
</html>
相关推荐
重生之小比特18 分钟前
【初阶C++】string
开发语言·c++
Dream Cosmos20 分钟前
C++继承详解(上):继承规则、父子类转换与作用域隐藏
c++
skr爱码士21 分钟前
15_国际化和本地化:tr()、ts 文件、QM 文件、多语言切换
c++·qt·ui·客户端
汉克老师1 小时前
CSP-J 初赛(以满分为目标):第二十一课 《树与二叉树基础—— 一棵树,为什么会成为计算机最重要的数据结构之一?》
c++·csp-j·小学生·学c++编程
别动我齐刘海1 小时前
从0到1独立搭建机器人软件系统
c++·人工智能·神经网络·opencv·目标检测·机器学习·机器人
dear_bi_MyOnly1 小时前
数组字符串深度解析:从入门到卡牌实战
开发语言·c++·学习
降临-max1 小时前
Selenium(HTML+JavaScript&DOM+Selenium IDE)
自动化测试·selenium·测试工具·html
用户298698530142 小时前
PDF 转 HTML 全攻略:三种方法轻松搞定网页转换
c#·html·.net
小欣加油2 小时前
Leetcode2058 找出临界点之间的最小和最大距离
数据结构·c++·算法·leetcode·职场和发展
王老师青少年编程2 小时前
2026年山东省小学组【信息学体验营】复赛真题及题解T2:小兔子爬楼梯
c++·真题·山东省·csp·信奥赛·复赛·信息学体验营