XML文件生成C++代码(基于rapidxml)
简述
与XML文件生成C++代码(基于pugixml)中的功能一致,只是这里改用的rapidxml来实现。就不多说了,直接放代码。
代码
#include "rapidxml-1.13/rapidxml.hpp"
#include "rapidxml-1.13/rapidxml_utils.hpp"
#include "rapidxml-1.13/rapidxml_iterators.hpp"
#include "rapidxml-1.13/rapidxml_print.hpp"
#include <algorithm>
#include <cstdio>
// XML节点名称中可以包含C++变量名不支持的字符
// 需要将其规范化,使之能够正常作为C++变量名
std::string normalVarName(std::string s)
{
// XML 元素必须遵循以下命名规则:
// 名称可以含字母、数字以及其他的字符
// 名称不能以数字或者标点符号开始
// 名称不能以字符 “xml”(或者 XML、Xml)开始
// 名称不能包含空格
// 可使用任何名称,没有保留的字词。
// 如果只需要C++编译通过,完全可以将s转换为base16表示的字符串即可
// 这里我只对 : . , ; 做一下处理,其它的就先不管了
for(std::size_t pos = s.find_first_of(":.,;");
pos != std::string::npos; pos = s.find_first_of(":.,;",pos+1)){
s[pos] = '_';
}
return s;
}
// 对于节点的值,它有可能包含需要转义的字符,需要进行转义(未考虑C++原始字面常量)
std::string toEscape(const std::string& s)
{
std::string s2;
s2.reserve(s.size());
for(std::size_t i=0;i<s.size();++i){
switch (s[i]) {
case '"':
case '\\':
s2.push_back('\\');
break;
default:
break;
}
s2.push_back(s[i]);
}
return s2;
}
bool TraversalXml(rapidxml::xml_node<char>& node,int level = 0)
{
std::string s(level*4,32);
if(level == 0){ /*表明是root节点*/
puts("rapidxml::xml_document<char> xmldocObject;\n"
"rapidxml::xml_document<char>* xmldoc = &xmldocObject;\n"
"{\n"
" rapidxml::xml_node<char>* decl = \n"
" xmldoc->allocate_node(rapidxml::node_pi,\n"
" xmldoc->allocate_string(\"xml version='1.0' encoding='utf-8'\"));\n"
" xmldoc->append_node(decl);\n"
"}");
puts("{");
}
// 获取节点名称
std::string nodeName(node.name(),node.name_size());
std::string nodeValue(node.value(),node.value_size());
std::string parentName;
if(node.parent() == NULL || node.parent()->name_size() == 0){
parentName = "xmldoc";
} else {
parentName = std::string(node.parent()->name(),node.parent()->name_size());;
}
// pugixml这里有点问题,不知道是不是bug(我对XML规范和pugixml都不是很熟)
// 一个节点A没有子节点的时候,它也能获取到它的一个子节点,这个子节点的name是
// 空的,value与节点A相同,其它的属性信息也是没有的。
// 所以在这里一些地方写的会比较别扭
// 这里使用rapidxml的时候也有这个问题,所以我觉得可能是对于没有子节点的的节点
// 它的值就是它的子节点吧。这只是我的猜想,并未查阅相关规范。
if(!nodeName.empty()){
printf("%s{/*add %s*/\n",s.c_str(),nodeName.c_str());
// 输出添加子节点代码
if(nodeValue.empty()){
printf("%s rapidxml::xml_node<char>* %s = xmldoc->allocate_node(\n"
"%s rapidxml::node_element,\"%s\",NULL);\n",
s.c_str(),normalVarName(nodeName).c_str(),
s.c_str(),nodeName.c_str());
}else{
printf("%s rapidxml::xml_node<char>* %s = xmldoc->allocate_node(\n"
"%s rapidxml::node_element,\"%s\",\"%s\");\n",
s.c_str(),normalVarName(nodeName).c_str(),
s.c_str(),nodeName.c_str(),toEscape(nodeValue).c_str());
}
// 输出添加子节点到父节点代码
printf("%s %s->append_node(%s);\n",
s.c_str(),normalVarName(parentName).c_str(),
normalVarName(nodeName).c_str());
// 逐个输出属性信息添加代码
for(rapidxml::xml_attribute<char>* attr = node.first_attribute();
attr != NULL; attr = attr->next_attribute()){
// 输出属性信息添加代码
printf("%s %s->append_attribute(\n"
"%s xmldoc->allocate_attribute(\"%s\",\"%s\"));\n",
s.c_str(),normalVarName(nodeName).c_str(),
s.c_str(),attr->name(),attr->value());
}
}
// 遍历子节点
for(rapidxml::xml_node<char>* subnode = node.first_node();
subnode != NULL;subnode = subnode->next_sibling()){
TraversalXml(*subnode,level+1);
}
// 与前面匹配
if(!nodeName.empty()){
printf("%s}/*end %s*/\n\n",s.c_str(),nodeName.c_str());
}
// 与前面匹配
if(level == 0){
puts("}");
}
return true;
}
int main(int argc,char** argv)
{
if(argc != 2){
puts("Usage:....");
return 0;
}
try{
rapidxml::file<char> xmlfile(argv[1]);
rapidxml::xml_document<char> doc;
doc.parse<0>(xmlfile.data());
TraversalXml(doc);
}
catch(std::exception& e){
puts(e.what());
}
return 0;
}
XML文件生成C++代码(基于rapidxml)的更多相关文章
- XML文件生成C++代码(基于pugixml)
简述 在一个项目中需要用到XML的解析和生成,知乎上有人推荐rapidxml和pugixml等库.RapidXML一看库还比较大,就先研究一下pugixml了. 因为对解析XML的需求不大(都是一些很 ...
- 使用XML文件和Java代码控制UI界面
Android推荐使用XML文件设置UI界面,然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller,是模型(model)-视图(view)-控制 ...
- Android color(颜色) 在XML文件和java代码中
Android color(颜色) 在XML文件和java代码中,有需要的朋友可以参考下. 1.使用Color类的常量,如: int color = Color.BLUE;//创建一个蓝色 是使用An ...
- 根据xml文件生成javaBean
原 根据xml文件生成javaBean 2017年08月15日 18:32:26 吃完喝完嚼益达 阅读数 1727 版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出 ...
- eclips运行generatorConfig.xml文件生成代码
描述: 如何通过eclips工具来运行 generatorConfig.xml 文件来自动生成代码并获取数据(类似于mybaits逆向生成)? mybatis-generator:generate 2 ...
- WebAPI使用多个xml文件生成帮助文档
一.前言 上篇有提到在WebAPI项目内,通过在Nuget里安装(Microsoft.AspNet.WebApi.HelpPage)可以根据注释生成帮助文档,查看代码实现会发现是基于解析项目生成的xm ...
- WebAPI使用多个xml文件生成帮助文档(转)
http://www.cnblogs.com/idoudou/p/xmldocumentation-for-web-api-include-documentation-from-beyond-the- ...
- Android(java)学习笔记185:xml文件生成
1.xml文件: 用元素描述数据,跨平台. 2.利用传统的方式创建xml文件,下面是一个案例: 设计思路:建立一个学生管理系统,创建xml文件保存学生信息: (1)首先是布局文件activity_ma ...
- 【转】WebAPI使用多个xml文件生成帮助文档
来自:http://www.it165.net/pro/html/201505/42504.html 一.前言 上篇有提到在WebAPI项目内,通过在Nuget里安装(Microsoft.AspNet ...
随机推荐
- tmux 终端分屏利器使用
介绍 Tmux 是一个工具,用于在一个终端窗口中运行多个终端会话. 不仅如此,你还可以通过 Tmux 使终端会话运行于后台或是按需接入.断开会话,这个功能非常实用. 很好的工具,记录一下,以后要常用. ...
- 如何得知当前机器上安装的PowerShell是什么版本的?
$PSVersionTable.PSVersion 参考资料 ================ http://stackoverflow.com/questions/1825585/determi ...
- 算法-强连通分量和Kosaraju算法
有向图中,连通性比较好理解,如果两个顶点V和顶点W是可达的,可以称之为强连通的,即存在路径A→B,同时也存在一条有向路径B→A.从之前的有向环的判定过程中其实我们可以得到一个结论就是两个是强连通的当且 ...
- 大数据开发实战:Hive优化实战3-大表join大表优化
5.大表join大表优化 如果Hive优化实战2中mapjoin中小表dim_seller很大呢?比如超过了1GB大小?这种就是大表join大表的问题.首先引入一个具体的问题场景,然后基于此介绍各自优 ...
- javascript计算字符串长度
javascript计算字符串长度 学习了:https://blog.csdn.net/u012934325/article/details/75214847 function getByteLen( ...
- Python编译exe
有几种办法,选择py2exe,从pip安装,还不行,下载看起来都比较老,还是在csdn上下载了一个64位版本for2.7的 http://download.csdn.net/download/henu ...
- Modbus常用功能码协议详解
Modbus常用功能码协议详解 01H-读线圈状态 1)描述:读从机线圈寄存器,位操作,可读单个或者多个: 2)发送指令: 假设从机地址位0x01,寄存器开始地址0x0023,寄存器结束抵制0x003 ...
- iis 防火墙防止恶意ip攻击
今天发现服务器里,一个IP不停的占用我的网络资源,然后在防火墙里配置,将其禁止访问,网络很快降了下来. 这个恶意的IP是 115.171.60.62
- Python requests如何将第一个请求得到的 cookie 通过 POST 提交给第二个请求
#coding=utf-8 import requests import json url_login, url_test = "http://192.168.0.162/login&quo ...
- 微服务架构实践 - 你只懂docker与spring boot就够了吗?
微服务架构实践 - 你只懂docker与spring boot就够了吗? 作者 浮云发发 已关注 2017.02.27 02:50* 字数 2613 阅读 2583评论 6喜欢 35赞赏 2 微服务并 ...