将数据库文件导出XML文件以及解析XML文件生成数据库文件的处理方法

思路:将数据库所有要导出的信息通过sql语句得到,存储到结构体中,然后将结构体的内容通过自定义的xml格式导出。

此方法使用的是TinyXML2库,TinyXML2是一个开源的解析XML的库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。

1、配置TimyXML2

从这里下载,这里只需将头文件和CPP文件放到自己的项目当中即可。

项目结构如下:

2、使用TinyXML2创建XML文件

其实无非就是以下几个步骤,然后进行逻辑上的整合:

第一步:添加声明,xml声明包含了版本和编码格式

第二步:创建根节点

第三步:创建子节点

第四步:为子节点增加内容

第五步:为子节点增加属性

第六步:保存xml文件

下面是由数据库文件生成的xml结构,结构为:可以导出多个数据库,每个数据库包括多个表,每个表有多个列和行数据。

<?xml version="1.0" encoding="UTF-8"?>
<databases><database><name>DB1</name><tables><table><name>TB1</name><ddl>sql1</ddl><columns><column><name>col1</name><type>int</type></column></columns><rows><row><value column="0">row1</value></row></rows></table></tables></database><database><name>DB1</name><tables><table><name>TB1</name><ddl>sql1</ddl><columns><column><name>col1</name><type>int</type></column></columns><rows><row><value column="1" null="true"/></row></rows></table></tables></database>
</databases>

Export.cpp 代码如下:

#include <iostream>
#include <vector>
#include "tinyxml2.h"
using namespace std;
using namespace tinyxml2;//全局变量(省事了)
tinyxml2::XMLDocument doc;typedef struct
{string value;string colNum;string valNull;
}RowContent;typedef struct
{vector<RowContent> rowContents;
}Row;typedef struct
{string name;string type;
}Column;typedef struct
{string name;               //数据表名string ddl;                   //用来存放创建表的sql语句vector<Column> colunms;vector<Row> rows;
}Table;typedef struct
{string name;               //数据库名vector<Table> tables;       //数据库表的集合
}Database;//创建数据表行数据节点
tinyxml2::XMLElement * GenerateRowValueElements(RowContent rowContent)
{//行的父节点tinyxml2::XMLElement* childNodeRowValue = doc.NewElement("value");if (rowContent.value != ""){//为子节点增加内容tinyxml2::XMLText* ContentNodeRowValue = doc.NewText(rowContent.value.c_str());childNodeRowValue->InsertFirstChild(ContentNodeRowValue);//为子节点增加属性childNodeRowValue->SetAttribute("column", rowContent.colNum.c_str());}else{//为子节点增加属性childNodeRowValue->SetAttribute("column", rowContent.colNum.c_str());childNodeRowValue->SetAttribute("null", "true");}return childNodeRowValue;
}//创建数据表行数据节点
tinyxml2::XMLElement * GenerateRowElements(Row row)
{//行的父节点tinyxml2::XMLElement* childNodeRow = doc.NewElement("row");//为Row添加子节点for (vector<RowContent>::iterator it = row.rowContents.begin(); it != row.rowContents.end(); ++it){childNodeRow->InsertEndChild(GenerateRowValueElements(*it));}return childNodeRow;
}//创建数据表列数据节点
tinyxml2::XMLElement * GenerateColunmElements(Column column)
{//列的父节点tinyxml2::XMLElement* childNodeColumn = doc.NewElement("column");//增加列名子节点tinyxml2::XMLElement* childNodeColName = doc.NewElement("name");//增加列属性子节点tinyxml2::XMLElement* childNodeType = doc.NewElement("type");//为子节点增加内容tinyxml2::XMLText* contentColName = doc.NewText(column.name.c_str());childNodeColName->InsertFirstChild(contentColName);tinyxml2::XMLText* contentType = doc.NewText(column.type.c_str());childNodeType->InsertFirstChild(contentType);childNodeColumn->InsertEndChild(childNodeColName);childNodeColumn->InsertEndChild(childNodeType);return childNodeColumn;
}//创建数据表节点
tinyxml2::XMLElement * GenerateTableElements(Table table)
{//表的父节点tinyxml2::XMLElement* childNodeTb = doc.NewElement("table");//增加表名子节点tinyxml2::XMLElement* childNodeTbName = doc.NewElement("name");//增加创建表的sql语句子节点tinyxml2::XMLElement* childNodeDll = doc.NewElement("ddl");//增加表的列信息子节点tinyxml2::XMLElement* childNodeColumns = doc.NewElement("columns");//增加表的行数据子节点tinyxml2::XMLElement* childNodeRows = doc.NewElement("rows");//为子节点增加内容tinyxml2::XMLText* contentTbName = doc.NewText(table.name.c_str());childNodeTbName->InsertFirstChild(contentTbName);tinyxml2::XMLText* contentDll = doc.NewText(table.ddl.c_str());childNodeDll->InsertFirstChild(contentDll);childNodeTb->InsertEndChild(childNodeTbName);childNodeTb->InsertEndChild(childNodeDll);childNodeTb->InsertEndChild(childNodeColumns);childNodeTb->InsertEndChild(childNodeRows);//为Columns添加子节点for (vector<Column>::iterator it = table.colunms.begin(); it != table.colunms.end(); ++it){childNodeColumns->InsertEndChild(GenerateColunmElements(*it));}//为Rows添加子节点for (vector<Row>::iterator it = table.rows.begin(); it != table.rows.end(); ++it){childNodeRows->InsertEndChild(GenerateRowElements(*it));}return childNodeTb;
}//创建数据库节点
tinyxml2::XMLElement * GenerateDataBaseElements(Database database)
{//数据库的父节点tinyxml2::XMLElement* childNodeDB = doc.NewElement("database");//数据库名称子节点tinyxml2::XMLElement* childNodeDBName = doc.NewElement("name");//数据库表子节点tinyxml2::XMLElement* childNodeDBTables = doc.NewElement("tables");//为子节点增加内容tinyxml2::XMLText* contentDBName = doc.NewText(database.name.c_str());childNodeDBName->InsertFirstChild(contentDBName);childNodeDB->InsertEndChild(childNodeDBName);childNodeDB->InsertEndChild(childNodeDBTables);//添加database数组子节点for (vector<Table>::iterator it = database.tables.begin(); it != database.tables.end(); ++it){childNodeDBTables->InsertEndChild(GenerateTableElements(*it));}return childNodeDB;
}void GenerateXMLDocument(vector<Database> VecDataBases)
{//1.添加声明tinyxml2::XMLDeclaration* declaration = doc.NewDeclaration();doc.InsertFirstChild(declaration);//2.创建根节点tinyxml2::XMLElement* root = doc.NewElement("databases");doc.InsertEndChild(root);//3.添加database数组子节点for (vector<Database>::iterator it = VecDataBases.begin(); it != VecDataBases.end(); ++it){root->InsertEndChild(GenerateDataBaseElements(*it));}//4.保存xml文件doc.SaveFile("C:/Users/Administrator/Desktop/DataBaseXML.xml");//如果重复生成的话,全局变量一直存在,第二次生成会导致内容重复,所以需要清理,当然,局部变量的话不会存在这样的问题doc.Clear();
}int main()
{Database database0;database0.name = "DB1";Table table0;table0.name = "TB1";table0.ddl = "sql1";Column colunm0;colunm0.name = "col1";colunm0.type = "int";Row row0;RowContent rowContent0;rowContent0.value = "row1";rowContent0.colNum = "0";row0.rowContents.push_back(rowContent0);table0.rows.push_back(row0);table0.colunms.push_back(colunm0);database0.tables.push_back(table0);/**********************/Database database1;database1.name = "DB1";Table table1;table1.name = "TB1";table1.ddl = "sql1";Column colunm1;colunm1.name = "col1";colunm1.type = "int";Row row1;RowContent rowContent1;rowContent1.value = "";rowContent1.colNum = "1";row1.rowContents.push_back(rowContent1);table1.rows.push_back(row1);table1.colunms.push_back(colunm1);database1.tables.push_back(table1);/**********************/vector<Database> VecDataBases;VecDataBases.push_back(database0);VecDataBases.push_back(database1);GenerateXMLDocument(VecDataBases);return 0;
}

解释一下几个函数:

FirstChildElement(const char* value=0):获取第一个值为value的子节点,value默认值为空,则返回第一个子节点。
 
RootElement():获取根节点,相当于FirstChildElement的空参数版本;
 
const XMLAttribute* FirstAttribute() const:获取第一个属性值;
 
XMLHandle NextSiblingElement( const char* _value=0 ) :获得下一个兄弟节点。

3、解析上面创建的xml

对上面的第2节中的xml文件进行解析。

第一步,加载xml文件

第二步,找到根节点

第三步,获取子节点信息

Import.cpp代码如下:

#include <iostream>
#include <vector>
#include "tinyxml2.h"
using namespace std;
using namespace tinyxml2;tinyxml2::XMLDocument doc;typedef struct
{string value;
}RowContent;typedef struct
{vector<RowContent> rowContents;
}Row;typedef struct
{string ddl;vector<Row> rows;
}Table;typedef struct
{string name;vector<Table> tables;
}Database;//解析xml文件
void DP(vector<Database> & DataBases)
{{/*if (!root){return;}const char* content;content = root->GetText();if (content){cout << content << endl;}DP(root->FirstChildElement());DP(root->NextSiblingElement());*/}XMLDocument doc;doc.LoadFile("C:/Users/Administrator/Desktop/DataBaseXML.xml");XMLElement *XMLdataBases = doc.RootElement();XMLElement *XMLdataBase = XMLdataBases->FirstChildElement("database");while (XMLdataBase){XMLElement *DBName = XMLdataBase->FirstChildElement("name");Database database;database.name = (string)DBName->GetText();XMLElement *DBTables = XMLdataBase->FirstChildElement("tables");XMLElement *DBTable = DBTables->FirstChildElement("table");while (DBTable){XMLElement *XMLddl = DBTable->FirstChildElement("ddl");Table table;table.ddl = (string)XMLddl->GetText();XMLElement *DBRows = DBTable->FirstChildElement("rows");XMLElement *DBRow = DBRows->FirstChildElement("row");while (DBRow){Row row;XMLElement *XMLRowValue = DBRow->FirstChildElement("value");while (XMLRowValue){RowContent rowContent;const XMLAttribute *nullValue = XMLRowValue->FirstAttribute()->Next();if (!nullValue){rowContent.value = (string)XMLRowValue->GetText();}else{rowContent.value = "NULL";}row.rowContents.push_back(rowContent);XMLRowValue = XMLRowValue->NextSiblingElement();}table.rows.push_back(row);DBRow = DBRow->NextSiblingElement();}database.tables.push_back(table);DBTable = DBTable->NextSiblingElement();}DataBases.push_back(database);//下一个兄弟节点XMLdataBase = XMLdataBase->NextSiblingElement();}
}int main()
{vector<Database> DataBases;DP(DataBases);for (vector<Database>::iterator it = DataBases.begin(); it != DataBases.end(); ++it){Database database = *it;cout << database.name.c_str() << endl;for (vector<Table>::iterator it1 = database.tables.begin(); it1 != database.tables.end(); ++it1){Table table = *it1;cout << table.ddl.c_str() << endl;for (vector<Row>::iterator it2 = table.rows.begin(); it2 != table.rows.end(); ++it2){Row row = *it2;for (vector<RowContent>::iterator it3 = row.rowContents.begin(); it3 != row.rowContents.end(); ++it3){RowContent rowContent = *it3;cout << rowContent.value.c_str();}cout << endl;}}cout << endl;}system("pause");return 0;
}

提示:

只需要将数据库信息提取出来,把结构体Database的内容填充完整,最后将得到的Database数组传到方法中,即可得到相应文件。
 
可能会涉及到的sql语句:
   SELECT * FROM sqlite_master WHERE type=‘table’; //获得当前数据库所有数据表的名字以及创建表的sql语句
   PRAGMA table_info(‘tablename’); //获得所有表的列信息
 
输出的内容不全,按照自己需求自定义输出内容!

(C++)将数据库文件导出XML文件以及解析XML文件生成数据库文件的处理方法相关推荐

  1. python解析xml文件选用模块_python语言解析xml文件的常用的有两种方式

    MiniDom方式解析xml xml文件以data.xml为例,具体操作如下: data.xml: 保存用户的信息 Jordy 12345678 20 男 上网 功夫 34443678 18 男 功夫 ...

  2. 文件同步是什么?解析6个最佳的文件同步应用软件

    文件同步应用程序是一项服务或程序,它提供了一种便捷的方式来在多台计算机或移动设备上自动文件同步.在登录文件同步应用程序的任何地方,都可以使用相同的文件来打开,编辑,复制,流式传输等,就像在最初上传文件 ...

  3. 将idea中编译输出目录 classes 里的文件删掉,发现再次编译不能生成class文件

    将idea中编译输出目录 classes 里的文件删掉,发现再次编译不能生成class文件. 其他UP主给的解决方法如下: 解决方案:settings -> compiler 勾选自动编译选项 ...

  4. python 之模块之 xml.dom.minidom解析xml

    # -*- coding: cp936 -*- #python 27 #xiaodeng #python 之模块之 xml.dom.minidom解析xml #http://www.cnblogs.c ...

  5. python【模块】xml.etree.ElementTree 解析 xml

    pytho 模块 xml.etree.ElementTree 解析 xml 文章目录 pytho 模块 xml.etree.ElementTree 解析 xml 1. 什么是 XML? 2. Elem ...

  6. python 解析xml格式_Python解析XML文件

    1.概述 Python有三种方法解析XML:SAX,DOM,以及ElementTree: 1.SAX (simple API for XML ) python 标准库包含SAX解析器,SAX用事件驱动 ...

  7. python解析xml文件elementtree_Python中使用ElementTree解析XML示例

    [XML基本概念介绍] XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. 概念一: 复制代码 代码如下: # foo元素的起始标签 ...

  8. java dom xml 换行,dom4j解析xml文件_用DOM解析XML文件,怎么才能让解析出来的文本不用换行_dom解析xml文件...

    网友求助:dom4j解析xml文件_用DOM解析XML文件,怎么才能让解析出来的文本不用换行_dom解析xml文件 问题importjava.text.SimpleDateFormat; import ...

  9. XML格式文件详解及Java解析XML文件内容方法

    XML格式文件详解 1.概述 XML,即可扩展标记语言,XML是互联网数据传输的重要工具,它可以跨越互联网任何的平台,不受编程语言和操作系统的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者. ...

  10. c语言 自己编程解析 xml,C语言解析.XML文件

    最近手头上有个活在忙,中间很重要的一部分就是用C语言将.XML文件中想要的key和value读出来,与之前已有的值进行比较. 核心的.XML文件的格式如下: zzz xxx yyy 而我的思路是这样的 ...

最新文章

  1. 如何定时备份数据库并上传七牛云
  2. 无异常日志,就不能排查问题了???
  3. Enterprise Architect
  4. Google Maps API编程资源大全
  5. 分布式和集群区别以及分布式事务
  6. 筛选出1-n之间的个位数字为1的素数(Java代码实现)
  7. 浙江哪个地方的杨梅最出名?
  8. PBR理论基础3:基于图像的光照(上)
  9. 极客大学架构师训练营 组件设计原则 安全架构 防火墙ModSecurity 第21课 听课总结
  10. 74cms v5.0.1漏洞
  11. Ruby语言介绍(二)——Ruby基本语法(语言基础)
  12. 从高中缀学到身价过亿,这个80后值得喝彩!
  13. 有功,无功,视在功率的关系公式和图
  14. 1400——489C,520B,279B,479C
  15. R语言 |在官网查找程序包(packages)的官方说明书
  16. [BZOJ5139][Usaco2017 Dec]Greedy Gift Takers 权值线段树
  17. FlySee(绿色图片查看器)3.3.4 发布
  18. 傲慢与偏见之 - 山寨与创新
  19. html调用mp4视频播放不,为何html中嵌入mp4格式视频播放不了
  20. BZOJ 1787 AHOI2008 紧急集合 倍增LCA

热门文章

  1. emacs 快捷键(包括C/C++模式)
  2. 家用监控摄像头意想不到的五条用途
  3. [论文翻译]A SURVEY ON DEEP LEARNING METHODS FOR SEMANTIC IMAGE SEGMENTATION IN REAL-TIME
  4. mac安装mysql方法
  5. mysql设置固定ip地址访问_mysql设置指定ip访问,用户权限相关操作
  6. vCenter中上传镜像到存储失败
  7. 移动端测试——移动端基础
  8. 订阅发布功能Java实现
  9. 微信小程序发布详细步骤
  10. CI框架教程5——整合PHPExcel库应用