极光炫影 » 日志 » XML分析器演示
XML分析器演示
极光炫影 发表于 2007-03-24 15:02:58
这是一个简易得不能再简易了的XML分析器(其实是替某人完成的作业),
只能用来演示,
好久没写代码了,
不过写起来还是那么快乐
/*
Coded By JGShining
03/24/2007
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
using namespace std;
#define KEY_OPEN 1
#define KEY_CLOSE 2
#define KEY_FOUND 3
#define KEY_NOT_FOUND 4
#define KEY_ERROR 5
struct xml_tree_node
{
char* name;
char* value;
xml_tree_node* next_sibling;
xml_tree_node* first_child;
xml_tree_node()
{
name = NULL;
value = NULL;
next_sibling = NULL;
first_child = NULL;
}
~xml_tree_node()
{
if(first_child)
delete first_child;
if(next_sibling)
delete next_sibling;
if(name)
delete name;
if(value)
delete value;
}
};
struct bfs_node
{
xml_tree_node* tree_node;
int id;
};
void bfs_out(xml_tree_node* root)
{
if(root == NULL)
return;
int id = 1;
bfs_node node, t_node;
queue<bfs_node> bfs_q;
xml_tree_node* prev;
node.id = id++;
node.tree_node = root;
bfs_q.push(node);
while(!bfs_q.empty())
{
node = bfs_q.front();
bfs_q.pop();
prev = NULL;
printf("Element %d - %s : ", node.id, node.tree_node->name);
if(node.tree_node->value)
printf("%s", node.tree_node->value);
else
printf("null");
printf(", child:");
node.tree_node = node.tree_node->first_child;
for(; node.tree_node;)
{
t_node = node;
t_node.id = id++;
bfs_q.push(t_node);
if(prev)
putchar(',');
prev = node.tree_node;
printf(" Element %d", t_node.id);
node.tree_node = node.tree_node->next_sibling;
}
if(prev == NULL)
printf(" null\n");
else
putchar('\n');
}
}
int next_token(FILE* file)
{
int this_token;
while(EOF != (this_token = fgetc(file)))
{
if(this_token == '<' || this_token == '>')
break;
}
return this_token;
}
int next_key(FILE* file, char** buffer, int* type, int* start_pos)
{
int this_pos, key_length, token;
if('<' == (token = next_token(file)))
{
*start_pos = ftell(file) - 1;
token = fgetc(file);
if(token == '/')
*type = KEY_CLOSE;
else
{
*type = KEY_OPEN;
ungetc(token, file);
}
this_pos = ftell(file);
if('>' == (token = next_token(file)))
{
key_length = ftell(file) - this_pos - 1;
if(key_length == 0)
*buffer = NULL;
else
{
*buffer = new char[key_length + 1];
this_pos = ftell(file);
fseek(file, this_pos - key_length - 1, SEEK_SET);
fread(*buffer, key_length, 1, file);
(*buffer)[key_length] = 0;
fseek(file, this_pos, SEEK_SET);
}
}
else
return KEY_ERROR;
}
else if(token == EOF)
return KEY_NOT_FOUND;
else
return KEY_ERROR;
return KEY_FOUND;
}
void read_value(FILE* file, char** buffer, int start_pos, int end_pos)
{
if(end_pos <= start_pos)
{
*buffer = NULL;
return;
}
int this_pos = ftell(file);
fseek(file, start_pos, SEEK_SET);
*buffer = new char[end_pos - start_pos + 1];
fread(*buffer, end_pos - start_pos, 1, file);
(*buffer)[end_pos - start_pos] = 0;
fseek(file, this_pos, SEEK_SET);
}
bool parse(FILE* file, xml_tree_node* parent, int start_pos)
{
xml_tree_node* node = NULL, *prev_child = NULL;
char* key_name;
int type, next_pos, res;
while(KEY_FOUND == (res = next_key(file, &key_name, &type, &next_pos)))
{
if(type == KEY_CLOSE && strcmp(key_name, parent->name) == 0)
{
if(parent->first_child == NULL)
read_value(file, &(parent->value), start_pos, next_pos);
return true;
}
else if(type == KEY_OPEN)
{
node = new xml_tree_node;
node->name = key_name;
if(prev_child == NULL)
parent->first_child = node;
else
prev_child->next_sibling = node;
prev_child = node;
if(!parse(file, node, ftell(file)))
return false;
}
else
return false;
}
return false;
}
int main(int argc, char** argv)
{
xml_tree_node* root;
FILE* file;
char* key_name;
int type, start_pos, res;
freopen("parse_result.txt", "w", stdout);
if(argc < 2)
{
printf("not enough parameters\n");
return 0;
}
if(file = fopen(argv[1], "rb"))
{
res = next_key(file, &key_name, &type, &start_pos);
if(res == KEY_FOUND && type == KEY_OPEN)
{
root = new xml_tree_node;
root->name = key_name;
if(parse(file, root, ftell(file)))
bfs_out(root);
else
printf("file format error\n");
delete root;
}
else if(res == KEY_ERROR)
printf("file format error\n");
fclose(file);
}
else
printf("failed to open XML file\n");
return 0;
}
曾经的这一天...
- » 2006年: NIT的大牛们到访
相关日志:
收藏:
QQ书签
del.icio.us
订阅:
Google
抓虾
