(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> <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> <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()); //为子节点增加属性 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(); 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数组传到方法中,即可得到相应文件。
# c++ # 经验分享 # 数据库 # xml
可能会涉及到的sql语句:
SELECT * FROM sqlite_master WHERE type=‘table’; //获得当前数据库所有数据表的名字以及创建表的sql语句
PRAGMA table_info(‘tablename’); //获得所有表的列信息
输出的内容不全,按照自己需求自定义输出内容!
所有评论(0)