用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 <algorithm>
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<string> nameStack;
wstack<CSNode> nodeStack;
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] == '/t' || _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] == '/t' || _fileCope[pn] == 0x09 || _fileCope[pn] == 0x0d)
{
pn++;
continue;
}
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] == '/t' || _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;
}

目前该程序只能解析3层结构的XML文件
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值