(C++)将数据库文件导出XML文件以及解析XML文件生成数据库文件的处理方法
将数据库文件导出XML文件的(C++)处理方法此方法使用的是TinyXML2库,TinyXML2是一个开源的解析XML的库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。1、配置TimyXML2从这里下载,这里只需将头文件和CPP文件放到自己的项目当中即可。2、使用TinyXML2创建XM
将数据库文件导出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’); //获得所有表的列信息
输出的内容不全,按照自己需求自定义输出内容!
更多推荐
所有评论(0)