新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 关于 XML 的一般性技术讨论,提供 XML入门资料 和 XML教程
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - XML技术『 XML基础 』 → [转帖]用Expat處理你的XML資料(1) 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4757 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: [转帖]用Expat處理你的XML資料(1) 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     emmali808 美女呀,离线,快来找我吧!
      
      
      等级:大二(研究C++)
      文章:56
      积分:270
      门派:XML.ORG.CN
      注册:2008/3/11

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给emmali808发送一个短消息 把emmali808加入好友 查看emmali808的个人资料 搜索emmali808在『 XML基础 』的所有贴子 引用回复这个贴子 回复这个贴子 查看emmali808的博客楼主
    发贴心情 [转帖]用Expat處理你的XML資料(1)

    用Expat處理你的XML資料(1)
    By Sam .... 2006/07/07
        當你的程式之間需要傳遞資料時,你會怎麼做?譬如說設定檔資料,使用一個最簡單的型式:
    『id := value』
    那如果設定值很複雜又有層次呢?我甚至還看過透過網路把整個二進位資料結構memory複製到網路去,由接受端宣告一個一模一樣的資料結構在memcpy......(當然,看到這種程式要我處理我會有想自殺的感覺...)。
    其實XML是一個很好的規範,他的可擴充性讓程式可以自己去處理自己要的資料,也不會因為多了一個欄位讓天下大亂(我的世界就處在混亂中...ㄏㄏ)。但是要你面對XML這類的複雜結構時,我想很多人看到就感到害怕吧。還好這個世界甚麼不多,Open Source的library最多...ㄏㄏ,Expat是一個很不錯的XML parser library,原則上他是一個C library,而且可以在許多平台使用(好啦...有win32版本...不過我沒用過),Expat是一個stream導向的parser library,也就是說他會從data buffer一直讀進資料然後遇到不同的狀態改變做不同的處理。
    經過一番google搜尋後發現Expat的文章不多,只有看到一篇在xml.com的介紹文章,當然expat也有不少wrapper library,譬如Python、Perl、Tcl、C++....等等,你可以直接去使用你習慣的語言的wrapper。這篇文章只是抱持著研究的精神的小小介紹,這裡我們使用C++語言來實作一個簡單的xml parser吧。
    使用Expat很簡單,首先當然你必須include相關的header file,Expat只會將兩個header file放進你的系統,分別是expat.h與expat_external.h(這裡以Expat2.0.0為例)。其實你只要加入expat.h,而expat_external.h會自動被加入。所以當然你必須有:
    #include <expat.h>
    在你要使用Expat library的程式碼中。因為這裡我使用C++語言,因此我定義一個自己的類別"MyParser"
    class MyParser
    {
    public:
        MyParser(string fname);
        virtual ~MyParser();
    }
    先不要緊張,這目前是一個do-nothing的類別,我在建構式的地方傳入一個XML檔案名稱的參數,我也將parser的動作在初始階段完成,讓我們看看建構式的內容。Expat需要一個XML_Parser的instance在整個parsing階段,因此我們第一步便要宣告一個XML_Parser然後建立它:
    XML_Parser parser;
    parser = XML_ParserCreate(NULL);
    if (!parser) {
       cout << "create XML_Parser error" << endl;
       return 0;
    }
    Expat使用callback function來處理狀態改變的動作,所以當你需要對某些tag做處理的時候你必須要設定相關的處理函式,這裡我們只對最簡單的型式做處理,因此我只設定start tag、end tag與default handler:
    ::XML_SetUserData(parser, this);
    ::XML_SetElementHandler(parser, expatStart, expatEnd);
    ::XML_SetDefaultHandler(parser, expatHandler);
    你可以使用this指標將自己傳給expat當成UserData;再來我們必須在類別內宣告相關的member function,因此我們的類別便宣告成:
    class MyParser
    {
    public:
       MyParser(string fname);
       virtual ~MyParser();
       static void expatStart(void *data, const XML_Char *el, const XML_Char **attr);
       static void expatEnd(void *data, const XML_Char *el);
       static void expatHandler(void *data, const XML_Char *s, int len);
    }
    你可以看到為了讓Expat的C library當成callback function我們將其宣告成static的member function,而當你要用類別內的成員變數或函式時,你不能直接呼叫或使用(沒忘記static吧),因此這個時候我們在XML_SetUserData(parser, this)做的動作便派上用場,你可以看到expatStart、expatEnd與expatHandler中第一個不定指標參數void *data便會是你在XML_SetUserData時傳入的第二個參數。因此假設你在這3個callback function中要使用一個類別函式"do_something()"時,你可以這樣做:
    ((MyParser *)data)->do_something();
    這樣一來,我們基本的宣告便完成,可以開始餵資料給XML_Parser了
    file = fopen(fname.c_str(), "r");
    do {
       len = fread(buf, 1, sizeof(buf), file);
       done = len < sizeof(buf);
       if (!XML_Parse(parser, buf, len, done))
       done = 1;
    } while (!done);
    ::XML_ParserFree(parser);
    fclose(file);
    當然最後不要忘了釋放掉我們宣告的parser與關閉檔案。一個最簡單的Expat動作流程就是這麼簡單.......待續

       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/3/14 12:55:00
     
     emmali808 美女呀,离线,快来找我吧!
      
      
      等级:大二(研究C++)
      文章:56
      积分:270
      门派:XML.ORG.CN
      注册:2008/3/11

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给emmali808发送一个短消息 把emmali808加入好友 查看emmali808的个人资料 搜索emmali808在『 XML基础 』的所有贴子 引用回复这个贴子 回复这个贴子 查看emmali808的博客2
    发贴心情 
    先占一下,原文的网址:http://joepasscheng.googlepages.com/expat-1
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/3/14 12:57:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 XML基础 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/12/27 15:36:33

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    42.969ms