简述

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)的更多相关文章

  1. XML文件生成C++代码(基于pugixml)

    简述 在一个项目中需要用到XML的解析和生成,知乎上有人推荐rapidxml和pugixml等库.RapidXML一看库还比较大,就先研究一下pugixml了. 因为对解析XML的需求不大(都是一些很 ...

  2. 使用XML文件和Java代码控制UI界面

    Android推荐使用XML文件设置UI界面,然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller,是模型(model)-视图(view)-控制 ...

  3. Android color(颜色) 在XML文件和java代码中

    Android color(颜色) 在XML文件和java代码中,有需要的朋友可以参考下. 1.使用Color类的常量,如: int color = Color.BLUE;//创建一个蓝色 是使用An ...

  4. 根据xml文件生成javaBean

    原 根据xml文件生成javaBean 2017年08月15日 18:32:26 吃完喝完嚼益达 阅读数 1727 版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出 ...

  5. eclips运行generatorConfig.xml文件生成代码

    描述: 如何通过eclips工具来运行 generatorConfig.xml 文件来自动生成代码并获取数据(类似于mybaits逆向生成)? mybatis-generator:generate 2 ...

  6. WebAPI使用多个xml文件生成帮助文档

    一.前言 上篇有提到在WebAPI项目内,通过在Nuget里安装(Microsoft.AspNet.WebApi.HelpPage)可以根据注释生成帮助文档,查看代码实现会发现是基于解析项目生成的xm ...

  7. WebAPI使用多个xml文件生成帮助文档(转)

    http://www.cnblogs.com/idoudou/p/xmldocumentation-for-web-api-include-documentation-from-beyond-the- ...

  8. Android(java)学习笔记185:xml文件生成

    1.xml文件: 用元素描述数据,跨平台. 2.利用传统的方式创建xml文件,下面是一个案例: 设计思路:建立一个学生管理系统,创建xml文件保存学生信息: (1)首先是布局文件activity_ma ...

  9. 【转】WebAPI使用多个xml文件生成帮助文档

    来自:http://www.it165.net/pro/html/201505/42504.html 一.前言 上篇有提到在WebAPI项目内,通过在Nuget里安装(Microsoft.AspNet ...

随机推荐

  1. 机器翻译评价指标之BLEU详细计算过程

    原文连接 https://blog.csdn.net/guolindonggld/article/details/56966200 1. 简介 BLEU(Bilingual Evaluation Un ...

  2. Statistical Artifact (error)

    In natural science and signal processing, an artifact is any error in the perception or representati ...

  3. windows取证

    工具网站 : http://www.ntsecurity.nu/toolbox/ 命令行历史 :命令行模式 CMD 中使 doskey /history 命令可以显示前面输入的命令情况(例如使用 cl ...

  4. [leetcode]Search in Rotated Sorted Array II @ Python

    原题地址:https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ 题意: Follow up for "Sea ...

  5. jQuery-append添加元素click无效

    很久没有使用jQuery,做项目的时候遇到一个小问题就是网页加载之后的append的元素是可以执行click事件,网页加载完成之后的,再次append的元素不执行click事件,简单的通过ul模拟一下 ...

  6. 机器学习、NLP、Python和Math最好的150余个教程(建议收藏)

    编辑 | MingMing 尽管机器学习的历史可以追溯到1959年,但目前,这个领域正以前所未有的速度发展.最近,我一直在网上寻找关于机器学习和NLP各方面的好资源,为了帮助到和我有相同需求的人,我整 ...

  7. 建模角度理解word embedding及tensorflow实现

    http://www.jianshu.com/p/d44ce1e3ec2f 1. 前言 本篇主要介绍关键词的向量表示,也就是大家熟悉的word embedding.自Google 2013 年开源wo ...

  8. Netflix推荐系统:从评分预测到消费者法则

    http://in.sdo.com/?p=11 原文链接:Netflix recommendations: beyond the 5 stars (Part 1), (Part 2) 原文作者:Xav ...

  9. Python练习环境搭建-引入预定义数据

    学习Python,有大量的需要在交互式环境下练习的项目,这时数据来源就很麻烦了,手工输入太慢,写到程序中,运行方便,但各种实验又不方便.昨天试了半天也无法从vscode完美地跳出到交互环境. 今天反过 ...

  10. vue版本冲突解决办法

    ERROR in Vue packages version mismatch: vue@2.1.4 vue-template-compiler@2.1.5 This may cause things ...