今天我来看一个简单的写xml文件的一个类,该类非常简单,简单到其实就是C语言的文件操作再上上一点STL的知识,这个类没有MarkupSTL这个C++读写xml文件这么强大,但是如果我们项目中要操作xml文件,完全可以用这个替代或者在这个的基础上进行扩展。
这个xmlwriter类是用来写xml文件,并不能用来读取xml文件,是一个澳大利亚人写的,网址如下:http://www.codeproject.com/Articles/13498/XMLWriter-A-simple-reusable-class,共包含两个文件,一个头文件和一个cpp文件,在代码中我已经添加必要的注释,应该很容易就看懂了。
xmlwriter.h文件:
typedef stack<string> StackStrings; class xmlwriter{ public: xmlwriter(string sTmp); ~xmlwriter(); void CreateChild(string sTag,string sValue); //创建子标签 void Createtag(string sTag); //创建标签 void CloseLasttag(); //关闭标签 void CloseAlltags(); //关闭所有标签 void AddAtributes(string sAttrName, string sAttrvalue); //添加标签的属性 void AddComment(string sComment); //添加注释 private: string sXmlFile; //xml文件 vector<string> vectAttrData; //存放属性 FILE *fp; int iLevel; //用于排版,输出tab键的个数 StackStrings sTagStack; //标签栈 };
xmlwriter.cpp文件:
#include "xmlwriter.h" #include <stdarg.h> xmlwriter::xmlwriter(string sTmp) { sXmlFile = sTmp; fp = NULL; iLevel = 0; fp = fopen(sXmlFile.c_str(),"w"); if(fp == NULL) { std::cout<<"Unable to open output file"; return; } else { fprintf(fp,"<?xml version=\"1.0\" encoding=\"UTF-8\" \?>"); } } xmlwriter::~xmlwriter() { if(fp != NULL) fclose(fp); vectAttrData.clear(); } void xmlwriter::Createtag(string sTag) //添加标签,如果标签有属性,必须先添加属性 { fprintf(fp,"\n"); for(int iTmp =0;iTmp<iLevel;iTmp++) fprintf(fp,"\t"); fprintf(fp,"<%s",sTag.c_str()); while(0 < vectAttrData.size()/2) { string sTmp = vectAttrData.back(); fprintf(fp," %s=", sTmp.c_str()); vectAttrData.pop_back(); sTmp = vectAttrData.back(); fprintf(fp,"\"%s\"", sTmp.c_str()); vectAttrData.pop_back(); } vectAttrData.clear(); fprintf(fp,">"); sTagStack.push(sTag); iLevel++; } void xmlwriter::CloseLasttag() { fprintf(fp,"\n"); iLevel--; for(int iTmp =0;iTmp<iLevel;iTmp++) fprintf(fp,"\t"); fprintf(fp,"</%s>",sTagStack.top().c_str()); sTagStack.pop(); return; } void xmlwriter::CloseAlltags() { while(sTagStack.size() != 0) { fprintf(fp,"\n"); iLevel--; for(int iTmp =0;iTmp<iLevel;iTmp++) fprintf(fp,"\t"); fprintf(fp,"</%s>",sTagStack.top().c_str()); sTagStack.pop(); } return; } void xmlwriter::CreateChild(string sTag,string sValue) //添加子标签,如果子标签有属性,必须先添加属性 { fprintf(fp,"\n"); for(int iTmp =0;iTmp<iLevel;iTmp++) fprintf(fp,"\t"); fprintf(fp,"<%s",sTag.c_str()); while(0 < vectAttrData.size()/2) { string sTmp = vectAttrData.back(); fprintf(fp," %s=", sTmp.c_str()); vectAttrData.pop_back(); sTmp = vectAttrData.back(); fprintf(fp,"\"%s\"", sTmp.c_str()); vectAttrData.pop_back(); } vectAttrData.clear(); fprintf(fp,">%s</%s>",sValue.c_str(),sTag.c_str()); } void xmlwriter::AddAtributes(string sKey, string sVal) //先添加值,在添加属性名称 { vectAttrData.push_back(sVal); vectAttrData.push_back(sKey); } void xmlwriter::AddComment(string sComment) { fprintf(fp,"\n"); for(int iTmp =0;iTmp<iLevel;iTmp++) fprintf(fp,"\t"); fprintf(fp,"<!--%s-->",sComment.c_str()); }
测试文件main.cpp:
xmlwriter MyXml("boby.xml"); MyXml.AddAtributes("age","25"); MyXml.AddAtributes("Profession","Software"); MyXml.Createtag("Boby"); MyXml.AddComment("Personal information"); MyXml.Createtag("Home"); MyXml.CreateChild("Address","Pazheparampil"); MyXml.CreateChild("Mobile","09844400873"); MyXml.CloseLasttag(); MyXml.AddComment("Office information"); MyXml.Createtag("Office"); MyXml.CreateChild("Address","Bangalore"); MyXml.CreateChild("Ph","0091234567"); MyXml.CloseLasttag(); MyXml.CloseAlltags();
执行程序就可以看到一个boby.xml文件的输出。
从这个小程序中学到的知识:
1、C语言文件操作
2、STL中的stack和vector的用法