| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 8844 人关注过本帖
标题:一个关于xml解析的程序
只看楼主 加入收藏
qldxsun
Rank: 4
等 级:业余侠客
帖 子:125
专家分:240
注 册:2011-6-4
结帖率:80%
收藏
已结贴  问题点数:20 回复次数:13 
一个关于xml解析的程序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define M 100
const m=10;
#define empty -1
#define succ 1
#define fail 0
#include<ctype.h>
//#define N 10000
typedef struct Dtnode
{
    int level;
    char node[50];
    struct Dtnode *next,*value,*lang,*down;
}Dtnode,*Dtptr;
int push(int num[],int &top,int x)
{   
    if(top==m-1)return fail;
    num[++top]=x;                                      //测试代码 printf("/%d\n",num[top]);
    return succ;                                       //测试代码 printf("//num[top]=%d",num[top]);
}                                                      //进站函数,top为数组下标,数字数组
int pop(int num[],int &top,int &x)
{
    if(top==empty)return fail;                         //测试代码 printf("测试num[top]=%d top=%d测试\n",num[top],x);
    x=num[top--];                                      //测试代码 printf("测试num[top]=%d top=%d测试\n",num[top],x);
    return succ;
}                                                      //退站函数,top为数组下标,数字数组                                          
void jiexi_str(char str[],int top,Dtptr &p,Dtptr &root,int different,Dtptr &level2)  
{
    int i=0,j=0;
    while(str[i]!='\0')
    {
        i++;
        if(str[i]=='"')
            break;
    }
    if(str[i]=='"')
    {
        
        //Dtptr q;
        int k=i;
        char strr[100];
        i=0;
        while(str[i]!=' ')
        {
            strr[i]=str[i];
            i++;
        }
        strr[i]='\0';                                        //printf("%d a ",top);puts(strr);//测试代码 //printf("解析levle  str\n");
        //strr把元素取走
        switch(top)
        {
        case 2:
            {   //元素节点
                Dtptr q;
                q=new Dtnode;
                strcpy(q->node,strr);
                //puts(q->node);
                q->level=2;
                level2=q;
                if(p->level==1)
                {
                    p->next=q;
                    q->next=p;
                    p=p->next;
                }
                if(p->level==3)
                {
                    p=p->down;
                    p->next=q;
                    q->next=root;
                    p=p->next;
                }
                break;
            }
        case 3:
            {   //元素节点
                Dtptr q;
                q=new Dtnode;
                q->next=NULL;
                p->down=q;
                strcpy(q->node,strr);
                //puts(q->node);
                q->down=level2;
                q->level=3;
                p=p->down;
                break;
            }
        default:
            {
                printf("ERROR\n");
                exit(0);
            }
        }                  
        j=0;
        i++;
        while(str[i]!='=')
        {
            strr[j]=str[i];
            i++,j++;
        }
        strr[j]='\0';                                         //测试代码 puts(strr);//printf("解析level  value str\n");
        //不需取走这个strr                                          
        k++,j=0;
        while(str[k]!='"')
        {
            strr[j]=str[k];
            j++,k++;
        }
        strr[j]='\0';                                    // printf("%d b ",top);puts(strr); //测试代码 //printf("解析  lang str\n");
        //strr把属性取走
        switch(top)
        {
        case 2:
            {   //值节点。属性域置空
                p->value=NULL;
                Dtptr q;
                q=new Dtnode;
                q->down=q->lang=q->next=q->value=NULL;
                strcpy(q->node,strr);
                //puts(q->node);
                p->lang=q;
                break;
            }
        case 3:
            {   //属性节点
                Dtptr q;
                q=new Dtnode;
                q->down=q->lang=q->next=q->value=NULL;
                strcpy(q->node,strr);
                //puts(q->node);printf("测试");
                p->lang=q;
                break;
            }
        default:
            {
                printf("ERROR\n");
                exit(0);
            }
        }            
    }
    else
    {
        printf("%d c ",top);puts(str);        //测试代码             //str直接建节点  分清level=1、2 和level =3是不同的
        switch(top)
        {
        case 1:
            {   //根节点。属性域,值域均置空
                p=new Dtnode;
                strcpy(p->node,str);
                p->lang=p->value=p->down=NULL;
                p->level=1;
                root=p;
                break;
            }
        case 3:
            {   //判断different,如果 different=2 值节点。属性域置空,如果 元素节点 different=1不置空
                Dtptr q;
                q=new Dtnode;
                strcpy(q->node,str);
                //puts(q->node);
                if(different==2)
                {
                    p->value=q;
                    q->down=q->lang=q->next=q->value=NULL;
                    //p->lang=NULL;///????
                }
                else
                {
                    p->down=q;
                    q->next=NULL;
                    q->lang=NULL;
                    q->level=3;
                    q->down=level2;
                    p=p->down;
                }
                break;
            }
        default:
            {
                printf("ERROR\n");
                exit(0);
            }
        }            
    }
}      
void bianli(Dtptr p)
{
    if(p==NULL)
        return;
    if(p->level!=2)
        puts(p->node);
    bianli(p->value);
    //bianli(p->lang);
    if(p->down==NULL)
        return;
    //printf("1");
    if(p->down->level==2)
        return;
    if(p->down->level!=2)
        bianli(p->down);
}   
void output_bianli(Dtptr root)
{
    Dtptr p;
    p=root;
    puts(p->node);
    while(1)
    {
        p=p->next;
        if(p==root)
            break;
        else
            bianli(p);
    }
}
void search_bianli(Dtptr p,Dtptr q,int &record,char name[])
{
    Dtptr root=q;
    if(p==NULL)
        return;
    //puts(p->node);
    if(strcmp(p->node,name)==0)
    {
        //q=p;
        record=1;
        printf("节点存在,请选择操作\n");
        printf("1、修改2、删除\n");
        int g;
        char newname[M];
        scanf("%d",&g);
        switch(g)
        {
        case 1:
            {
                printf("若存在多个相同名称的节点,则按建表顺序依次进行操作\n");
                char ch=getchar();
                printf("请输入修改的值\n");
                gets(newname);
                strcpy(p->node,newname);
                printf("修改后的文本为\n");
                output_bianli(q);
                break;
            }
        case 2:
            {
                //判断找到的节点是什么类型的节点
                printf("仅支持对相应文本所在的level=2的节点的删除。eg:bookstore中对Harry Potter这本书的删除\n");
                printf("若输入book,title,author,year等节点,删除后将整个树删除\n");//puts(name);
                if(strcmp(q->node,name)==0)
                {
                    printf("节点不可操作\n");
                    exit(0);
                }
                Dtptr p,r;
                int record=0;
                p=root;
                while(1)
                {
                    p=p->next;
                    if(root==p)
                        break;
                    r=p;
                    while(1)
                    {
                        //q=r;
                        r=r->down;
                        if(p==r)
                            break;/////////
                        if(strcmp(r->node,name)==0)
                        {
                            while(root->next!=p)
                                root=root->next;                                 //puts(r->node);
                            root->next=p->next;
                            delete p;
                            record=1;
                            break;
                        }
                        if(r->lang!=NULL)
                            if(strcmp(r->lang->node,name)==0)
                            {
                                while(root->next!=p)
                                    root=root->next;                                // puts(r->node);
                                root->next=p->next;
                                delete p;
                                record=1;
                                break;
                            }
                        if(r->value!=NULL)
                            if(strcmp(r->value->node,name)==0)
                            {
                                while(root->next!=p)
                                    root=root->next;                                 //puts(r->node);
                                root->next=p->next;
                                delete p;
                                record=1;
                                break;
                            }
                        if(record)
                            break;
                    }
                    if(record)
                        break;
                }
                printf("删除后的文本为\n");
                output_bianli(q);
                exot(0);
            }
        default:exit(0);
        }
    }
    search_bianli(p->value,q,record,name);
    search_bianli(p->lang,q,record,name);
    if(p->down==NULL)
        return;
    if(p->down->level==2)
        return;
    else
        search_bianli(p->down,q,record,name);
}
void search(Dtptr root,char name[])
{   
    char c;
    int record=0;                                //printf("1");
    printf("修改和删除输入1     插入输入2\n");
    int t;
    scanf("%d",&t);
    if(t==1)
    {
        int h=0;
        c=getchar();
        printf("请输入要操作的节点名\n");
        c=getchar();
        while(c!='\n')
        {
            name[h++]=c;
            c=getchar();
        }
        name[h]='\0';
        //puts(name);
        Dtptr p;
        p=root;
        if(strcmp(p->node,name)==0)
        {
            printf("该节点为根节点,不予操作\n");
            exit(0);
        }
        while(1)
        {
            p=p->next;
            if(p==root)
            {
                printf("该节点不存在或不再有相同名称节点\n");
                break;
            }
            search_bianli(p,root,record,name);
        }
    }
    if(t==2)
    {
        printf("仅支持第二层节点的插入\n");
        int j;
        printf("插在根节点后第一个输入1,最后一个输入2\n");
        scanf("%d",&j);
        switch(j)
        {
        case 1:
            {
                Dtptr p,q;
                p=new Dtnode;
                p->next=root->next;
                root->next=p;
                char str[]="new Dtnode";
                strcpy(p->node,str);
                p->lang=p->value=NULL;
                p->level=2;
                q=new Dtnode;
                p->down=q;
                q->down=p;
                q->lang=q->value=NULL;
                q->level=3;
                strcpy(q->node,str);puts(q->node);
                printf("其他操作按dom tree 建立方式建立,属重复操作,输出时会看到new Dtnode节点的输出\n");
                printf("插入后为\n");
                output_bianli(root);
            }
        case 2:
            {
                Dtptr r;
                r=root;
                while(1)
                {
                    if(r->next==root)
                        break;
                    r=r->next;
                }
                Dtptr p,q;
                p=new Dtnode;
                p->next=r->next;
                r->next=p;
                char str[]="new Dtnode";
                strcpy(p->node,str);
                p->lang=p->value=NULL;
                p->level=2;
                q=new Dtnode;
                p->down=q;
                q->down=p;
                q->lang=q->value=NULL;
                q->level=3;
                strcpy(q->node,str);puts(q->node);
                printf("其他操作按dom tree 建立方式建立,属重复操作,输出时会看到new Dtnode节点的输出\n");
                printf("插入后为\n");
                output_bianli(root);
                break;
            }
        }
    }
}
void main()
{
    printf("输出文本信息\n");
    Dtptr p,root,level2;
    FILE *pf;
    char ch,str[M];
    int i=0,s[100],top=-1,n=1,x,end=1,different;
    if((pf=fopen("file.txt","r"))==NULL)
    {
        printf("can not open the file\n");
        exit(0);
    }
    /*提前将0进栈*/
    if(push(s,top,0)!=1)
    {
        printf("ERROR\n");
        exit(0);
    }                                                      //测试代码printf("1");
    while(1)
    {
        if(n)
        {
            ch=fgetc(pf);
            if(feof(pf))
                break;
        }                                                  // printf("d");putchar(ch);printf("d\n");测试代码putchar(ch);                                             
        if(ch==' '||ch=='\n')
            continue;
        if(ch=='<')
        {
            different=1;
            n=1;
            ch=fgetc(pf);
            if(ch!='/')
            {                                                           //printf("s[top]=%d",s[top]);
                x=s[top]+1;                                            //printf("x=%4d",x);
                if(push(s,top,x)!=1)             //top++进栈
                {
                    printf("ERROR\n");
                    exit(0);
                }                                          //printf("进栈top%ds[top]%d\n",top,s[top]);
                i=0;
                while(ch!='>')
                {
                    str[i]=ch;
                    i++;
                    ch=fgetc(pf);
                }
                str[i]='\0';
                //puts(str);                                 //测试代码printf("f");puts函数输出后自动换行                  
            }
            else
            {                                                //printf("出栈前top%d=s[top]%d\n",top,s[top]);
                x=s[top];
                if(pop(s,top,x)!=1)              //top出栈
                {
                    printf("ERROR\n");
                    exit(0);
                }                                       //printf("出栈top%d===s[top]%d\n",top,s[top]);
                while(ch!='>')
                    ch=fgetc(pf);
                end=0;
            }
        }
        else
        {
            different=2;
            i=0;
            while(ch!='<')
            {
                str[i]=ch;
                i++;
                ch=fgetc(pf);
            }
            str[i]='\0';
            //puts(str);
            n=0;
        }                                           //printf("ERROR\n");这里的top是不变的,所以在switch时要考虑怎样让这个case 3 成功执行
        if(end)
            jiexi_str(str,top,p,root,different,level2);                               //解析str,分离出str中有用的信息        
        end=1;
    }
    printf("文本信息检查结束,输入  1:清屏     0:继续\n");
    int w;
    scanf("%d",&w);
    if(w)
        system("CLS");
    else
        ;
    //遍历输出
    printf("建立的树为\n");
    output_bianli(root);
    Dtptr q=root;
    char name[M];
    search(root,name);
}



一个简单的xlm解析器
文档结构:
<bookstore>

<book category="children">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

<book category="cooking">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>

<book category="web">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

</bookstore>
时间太少了,写的很匆忙。。。哪位有好一点的方式做啊。。。
目标就是建立一棵dom tree
能够解析文档,并且支持插入删除和修改(本人觉得插入和删除就是扯淡。。。)
老师留的作业。。。没办法。。。
版本信息不用做~

[ 本帖最后由 qldxsun 于 2011-6-9 23:10 编辑 ]
搜索更多相关主题的帖子: return 
2011-06-09 23:08
voidx
Rank: 12Rank: 12Rank: 12
来 自:邯郸
等 级:火箭侠
帖 子:1250
专家分:3538
注 册:2011-4-7
收藏
得分:3 
我只是表示,我很支持~
2011-06-09 23:48
qldxsun
Rank: 4
等 级:业余侠客
帖 子:125
专家分:240
注 册:2011-6-4
收藏
得分:0 
回复 2楼 voidx
额……支持是啥意思?
2011-06-10 00:54
laoyang103
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:内蒙古包头
等 级:贵宾
威 望:19
帖 子:3082
专家分:11056
注 册:2010-5-22
收藏
得分:3 
我也帮顶

                                         
===========深入<----------------->浅出============
2011-06-10 09:00
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
收藏
得分:3 
其实写的很烂。


可以去看看tinyxml是 怎么写的。
2011-06-10 10:05
烟雾中的迷茫
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
帖 子:621
专家分:1069
注 册:2011-2-9
收藏
得分:3 
回复 5楼 Devil_W
唉 我也表示支持  楼上别太打击楼主 都需要鼓励下啊 继续进步
2011-06-10 12:44
qldxsun
Rank: 4
等 级:业余侠客
帖 子:125
专家分:240
注 册:2011-6-4
收藏
得分:0 
回复 5楼 Devil_W
她要求用c语言完成……我知道写的挺烂的……所以要来求助怎么在这个基础上改进啊……
2011-06-10 13:08
voidx
Rank: 12Rank: 12Rank: 12
来 自:邯郸
等 级:火箭侠
帖 子:1250
专家分:3538
注 册:2011-4-7
收藏
得分:0 
楼主可以去看看 tinixml,确实写得很好。
虽然它是用 C++ 写的,楼主看看 C++ 的资料很快就能理解了。
2011-06-10 14:50
qldxsun
Rank: 4
等 级:业余侠客
帖 子:125
专家分:240
注 册:2011-6-4
收藏
得分:0 
回复 8楼 voidx
c++会的……但是写不成c的啊……我这段的解析过程完全就是在拼凑……xml自己也不会写……没准换一个文件就解析不了了……怎么实现c++到c的转变呢?
2011-06-10 16:45
啊C
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:84
专家分:177
注 册:2010-6-24
收藏
得分:3 
xml解析是什么东西,学习中..........

亲爱的朋友们动起手来吧,让我们一起迈向C语言的世界!
2011-06-10 21:20
快速回复:一个关于xml解析的程序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016397 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved