读取一个格式良好的XML文档,并按层次编号并输出 |
|
www.nanhushi.com 佚名 不详 |
#include <stdio.h> #include <memory.h> #include <string.h> #include <ctype.h> #define BUFSIZE 30 //XML文档结点 struct Node { int num; //结点编号 char name[BUFSIZE]; //结点名 char value[BUFSIZE]; //结点值 Node *parent; //父结点; Node *lsibling; //左同胞结点 Node *rsibling; //右同胞结点 Node *firstChild; //第一个子结点 Node *lastChild; //最后一个子结点 int childCount; //Examda提示: 子结点个数,这个可以不要,有这个要方便些,在插入和删除子结点时要维护 }; //从文件中读一个字符串,直到读到标记符为此 void ReadString(FILE *fp, char *buf) { char ch; char *p = buf; ch = fgetc(fp); do { if (p != buf || !isspace(ch)) //自动去掉首部空白 { *(p++) = ch; } ch = fgetc(fp); }while (!feof(fp) && (ch != '<' && ch != '>' || p == buf)); if ('<' == ch) //下一个标记开始 { fseek(fp, -1, SEEK_CUR); p--; } else if ('>' == ch) { *p = ch; } //以下代码为去掉buf的尾空白 while (p != buf && isspace(*p)) p--; *(++p) = '\0'; } //从文件中读取一个结点及其所有子结点 void ReadNode(FILE *fp, Node *node) { char buf[BUFSIZE]; Node *child = NULL; //当前子结点 ReadString(fp, buf); //读入开始标记 strcpy(node->name, &buf[1]); //只拷贝标记正文 node->name[strlen(node->name) - 1] = '\0'; while (1) { buf[0] = '\0'; ReadString(fp, buf); //读入下一个字符串 if ('<' == buf[0]) //读到标记 { if ('/' == buf[1]) //是结束标记 { break; //本层结束 } else //遇到开始标记,是子结点 { Node *p = new Node; memset(p, 0, sizeof(Node)); p->parent = node; if (child) //如果当前子结点不为空 { child->rsibling = p; p->lsibling = child; } else //为第一个子结点 { node->firstChild = p; } fseek(fp, -(long)strlen(buf), SEEK_CUR); //将文件指针拨回开始标记之前 ReadNode(fp, p); child = p; node->childCount ++; //子结点个数加一 } }
else //是结点值 { strcpy(node->value, buf); } } node->lastChild = child; //最后一个子结点 } //按层次访问所有结点并编号 void GetNum(Node *node) { static int num = 1; if (!node) return; node->num = num++; if (node->rsibling) //本层还未结束 GetNum(node->rsibling); else if (node->parent) { if (node->parent->rsibling) //找到右堂兄弟 GetNum(node->parent->rsibling->firstChild); else //进下一层 GetNum(node->parent->firstChild->firstChild); } else //本结点是根结点,直接进入下一层 GetNum(node->firstChild); } //按层次打印所有结点 void PrintNode(Node *node) { if (!node) return; printf("Element %d - %s: %s, child:", node->num, node->name, strlen(node->value) ? node->value : "null"); Node *p = node->firstChild; if (!p) printf("null"); while (p) { printf("Element %d", p->num); p = p->rsibling; if (p) printf(", "); } printf("\n"); if (node->rsibling) //本层还未结束 PrintNode(node->rsibling); else if (node->parent) { if (node->parent->rsibling) //找到右堂兄弟 PrintNode(node->parent->rsibling->firstChild); else //进下一层 PrintNode(node->parent->firstChild->firstChild); } else //本结点是根结点,直接进入下一层 PrintNode(node->firstChild); } //释放结点树 void FreeNode(Node *node) { Node *p = node->firstChild; while (p) { Node *q = p->rsibling; FreeNode(p); p = q; } delete node; } void main() { char filename[BUFSIZE]; FILE *fp; printf("Please enter XML filename:"); scanf("%s", filename); if (!(fp = fopen(filename, "r"))) { printf("Open file %s fail!\n"); } else { Node *node = new Node; memset(node, 0, sizeof(Node)); ReadNode(fp, node); fclose(fp); GetNum(node); PrintNode(node); FreeNode(node); } } 来源:考试大网
|
|
|
文章录入:杜斌 责任编辑:杜斌 |
|
上一篇文章: c++实现计算器的方法和代码 下一篇文章: C++辅导:C++函数虚函数功能失效? |
【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |
|
|