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 ...
随机推荐
- 机器翻译评价指标之BLEU详细计算过程
原文连接 https://blog.csdn.net/guolindonggld/article/details/56966200 1. 简介 BLEU(Bilingual Evaluation Un ...
- Statistical Artifact (error)
In natural science and signal processing, an artifact is any error in the perception or representati ...
- windows取证
工具网站 : http://www.ntsecurity.nu/toolbox/ 命令行历史 :命令行模式 CMD 中使 doskey /history 命令可以显示前面输入的命令情况(例如使用 cl ...
- [leetcode]Search in Rotated Sorted Array II @ Python
原题地址:https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ 题意: Follow up for "Sea ...
- jQuery-append添加元素click无效
很久没有使用jQuery,做项目的时候遇到一个小问题就是网页加载之后的append的元素是可以执行click事件,网页加载完成之后的,再次append的元素不执行click事件,简单的通过ul模拟一下 ...
- 机器学习、NLP、Python和Math最好的150余个教程(建议收藏)
编辑 | MingMing 尽管机器学习的历史可以追溯到1959年,但目前,这个领域正以前所未有的速度发展.最近,我一直在网上寻找关于机器学习和NLP各方面的好资源,为了帮助到和我有相同需求的人,我整 ...
- 建模角度理解word embedding及tensorflow实现
http://www.jianshu.com/p/d44ce1e3ec2f 1. 前言 本篇主要介绍关键词的向量表示,也就是大家熟悉的word embedding.自Google 2013 年开源wo ...
- Netflix推荐系统:从评分预测到消费者法则
http://in.sdo.com/?p=11 原文链接:Netflix recommendations: beyond the 5 stars (Part 1), (Part 2) 原文作者:Xav ...
- Python练习环境搭建-引入预定义数据
学习Python,有大量的需要在交互式环境下练习的项目,这时数据来源就很麻烦了,手工输入太慢,写到程序中,运行方便,但各种实验又不方便.昨天试了半天也无法从vscode完美地跳出到交互环境. 今天反过 ...
- vue版本冲突解决办法
ERROR in Vue packages version mismatch: vue@2.1.4 vue-template-compiler@2.1.5 This may cause things ...