用c读取XML文件
可以将XML文件的树(只有一个顶层节点).于是理所当然的可以用树作为XML的一种存储结构.
我将在这里用C++实现对简单的XML文件的解析.
1.选择存储结构:
树型数据结构有多种存储方式,我将用\"孩子兄弟表示法\定义如下:
typedef struct CSNode
{
int subNodes;
string data;
string name;
struct CSNode *firstChild,*nextsibling,*parent;
CSNode* operator=(CSNode cnode)
{
this->data = cnode.data;
this->firstChild = cnode.firstChild;
this->name = cnode.name;
this->nextsibling = cnode.nextsibling;
this->subNodes = cnode.subNodes;
return this;
}
}CSNode,*CSTree;
2.定义一个ADT,提供操作的公共接口.取名为 xml
class xml
{
public:
xml();
xml(char *fileName);
~xml();
CSNode& CreateTree(); // 建立存储结构
bool findData(const char *nodepos); // 查找节点值
bool findData(const char *partent, const char *child,string *data); // 查找节点值
bool readfile_(); // 读取xml源文件
void allocate(); // 释放节点资源
private:
string _fileCope;
char* _filename;
CSNode *head;
};
3.具体实现
#include \"stdafx.h\"
#include \"xmlCreate.h\"
#include \"wstack.h\"
#include using namespace std; xml::xml() { } xml::xml(char *fileName) : _filename(fileName) { head = new CSNode; } xml::~xml() { delete head; } CSNode& xml::CreateTree() { CSNode *p = new CSNode; CSNode *q = new CSNode; CSNode *s = new CSNode; wstack wstack string tmpstr; string name,tempname,rootName,headName; int noods = 0; bool subroot = true,next = false,poproot = false; unsigned short int enoods = 0; char ps; for (size_t i = 0; i < _fileCope.size(); ++i){ ps = _fileCope[i]; if (_fileCope[i] == ' ' || _fileCope[i] == '' || _fileCope[i] == '\' || _fileCope[i] == 0x09 || _fileCope[i] == 0x0d)continue; if (_fileCope[i] == '<' && _fileCope[i+1] != '/') { s = new CSNode; s->subNodes = 0; enoods = 0; } else if (_fileCope[i] == '>') { enoods = 0; s->name = tmpstr; nameStack.push(tmpstr); tmpstr = \"\"; noods++; size_t pn = i+1; char bug; while (pn < _fileCope.size()) { bug = _fileCope[pn]; if (_fileCope[pn] == ' ' || _fileCope[pn] == _fileCope[pn] == 0x09 || _fileCope[pn] == 0x0d) { pn++; continue; } || _fileCope[pn] '\' '' == || else break; } if (_fileCope[pn] == '<') { subroot = true; // 向上解析 } if(noods == 1){ // 保存根结点 head = s; head->parent = NULL; head->nextsibling = NULL; p = head; headName = head->name; } else if (subroot) { // 还没有解析到叶子结点 if (poproot) { p->nextsibling = s; p = p->nextsibling; poproot = false; } else{ s->parent = p; p->firstChild = s; p = p->firstChild; } } else if (!subroot) { // 解析到叶子结点(第2个) s->parent = p; p->nextsibling = s; p->firstChild = NULL; p = p->nextsibling; } } else if (_fileCope[i] == '<' && _fileCope[i+1] == '/') { enoods++; //p->firstChild = NULL; if (subroot && enoods < 2){ q = p->parent; rootName = q->name; subroot = false; } if(!subroot)q->subNodes++; string tname = nameStack.pop(); i = i+tname.size()+2; if (tmpstr.size() > 0) { s->data = tmpstr; tmpstr = \"\"; } else{ subroot = true; next = false; } if (tname == rootName) { p->nextsibling = NULL; p->firstChild = NULL; p = q; poproot = true; } else if (tname == headName) { q->nextsibling = NULL; } } else { enoods = 0; if (_fileCope[i] != '/')tmpstr += _fileCope[i]; } } delete s; return *head; } bool xml::readfile_() { ifstream infile(_filename,ios::binary); if (!infile) { //AfxMessageBox(\"Openfile failed!\"); return false; } bool lable = false; string _tfc(\"\"),_lable(\"\"); char c; while(infile.get(c))_tfc += c; for (size_t i = 0; i < _tfc.size(); ++i){ if (_tfc[i] == ' ' || _tfc[i] == '' || _tfc[i] == '\' || _tfc[i] == 0x09 || _tfc[i] == 0x0d)continue; if (_tfc[i] == '<' && _tfc[i+1] == '?') { lable = true; } else if (_tfc[i] == '?' && _tfc[i+1] == '>') { lable = false; _lable += _tfc[i]; _lable += _tfc[i+1]; i += 2; continue; } else if (_tfc[i] == '<' && _tfc[i+1] == '!' && _tfc[i+2] == '-') { lable = true; } else if (_tfc[i] == '-' && _tfc[i+1] == '-' && _tfc[i+2] == '>'){ lable = false; _lable += _tfc[i]; _lable += _tfc[i+1]; _lable += _tfc[i+2]; i += 3; } if (lable) _lable += _tfc[i]; else _fileCope += _tfc[i]; } return true; } bool xml::findData(const char *nodeName) { CSNode *p = head; string _nodeName = nodeName; return true; } bool xml::findData(const char *parent, const char *child,string *data) { CSNode *p = head->firstChild; string _parent(\"\"),_child(\"\"); bool isfound = false; while (p != NULL) { if (p->name == parent) { p = p->firstChild; while (p != NULL) { if (p->name == child) { *data = p->data; return true; } else p = p->nextsibling; } } else p = p->nextsibling; } return false; } void xml::allocate() { CSNode *p = head->firstChild; while (p != NULL) { CSNode *q = p->firstChild; while (q != NULL) { CSNode *s = q; q = q->nextsibling; if (s->name == \"RecvPort\") { cout << \"addd\" << endl; } delete s; } CSNode *m = p; p = p->nextsibling; delete m; } delete head; } 因篇幅问题不能全部显示,请点此查看更多更全内容