• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數據加載中……

            用YACC提高XML在C++中的解析性能

            在C++中,解析XML文件通常需要使用XML的解析類或庫,如DOM(DOCUMENT OBJECT MODEL)或SAX(SIMPLE API FOR XML),來解析XML文件,從而得到所需的數據。雖然比較方便,但是這種方法的效率不是很高,而把XML解析為C++的類,不但能提高解析的效率,而且還能提供給用戶面向對象的所有優點。

            一. 通常用DOMSAX解析XML文件所帶來的問題

            C++的程序在處理XML文件時常常會碰到解析的問題,有時需要根據一定的規則自己寫一個解析的類或包。因此,使用DOM或SAX來解析XML文件就顯得相對比較簡單。但是解析XML文件,一個非常重要的問題,即對于一些不同的語言,如JAVA,C++,XML沒有一個固定的標簽(如關鍵字),因此,開發一個適合于多種語言的通用解析器就顯得非常由必要。

            為了解決這個問題,開發出的這個解析器要能動態的列出標簽和解析XML文件的規則。即對于一個DOM的解析器要確定一個XML的模式文件,從而可以對XML文件中的內容進行有效性的確認。

            如果一個應用程序需要對XML文件進行不同的讀寫操作,DOM這個解析模式是非常合適的。因為它對于不同的XM文件,它的源代碼都不需要改變。但是,引用程序對XML文件的操作由可能進行的比較少,在這種情況下,如果使用DOM解析器解析XML文件,就加重程序的負擔。因此,根據不同的情況來選擇不同的解析器,使非常有必要的。而且有時還需自己開發出一個合適的解析器。

            二. XML模式(SCHEMAS)中派生出的靜態類

            和在某些情況下可以從XML模式中派生出C++類,對XML文件進行寫操作,提高程

            序的效率一樣,也可以從XML模式中派生出C++類,對XML文件進行解析,即讀操作。

            在C++中,為了生成某個語言的解析類,通常需要如下的步驟:首先需要編寫LEX規則或YACC語法的代碼,然后在根據特定的XML輸入文件生成LEXER和解析類。如下圖一所示:

            clip_image001[3]

            但是,這個過程非常繁瑣,而且對于每個不同的XML文件形式,都需要重復進行如下的步上的步驟。一個更有效的做法是先編寫一個用作翻譯的程序,把XML模式文件轉化為相對應的LEX規則或YACC語法,如下圖二所示:

            clip_image002[3]

            下面的程序(程序一)說明了對于一個XML的DTD文件ACMEPC.DTD所生成的語法。

            acmepcxml::XMLImporter importer;

            // Call the acmepcxml::Initialize() function to register the create functions

            // for the acmepcxml classes

            acmepcxml::Initialize();

            try {

            importer.ImportFromFile(sInputFileName, fPreprocess);

            }

            catch (eXactML::XException & e)

            {

            std::cerr << e.GetMsg() << std::endl;

            std::cerr << "in " << e.GetSourceFile() << " at line number " <<

            e.GetSourceLine() << std::endl;

            return 1;

            }

            cout << "Read in XML file with no errors." << std::endl;

            acmepc *acmepc = dynamic_cast (importer.GetXObject());

            cout << "Successfully cast XML importer root to acmepcxml::acmepc" << std::endl;

            // validate the data in the classes, throws an exception if bad.

            try {

            acmepc->IsValid();

            }

            catch (eXactML::XException & e) {

            cout << "Exception in validating XML" << std::endl;

            cout << e.GetMsg() << std::endl;

            eXactML::XMLImporterBase::DeleteImportedXObject(acmepc);

            return 1;

            }

            cout << "Validated acmepcxml::acmepc object" << std::endl;

            // generate the XML

            try {

            acmepc->EmitXML(cout);

            }

            catch (eXactML::XException e) {

            cout << "Exception in generating XML" << std::endl;

            cout << e.GetMsg() << std::endl;

            eXactML::XMLImporterBase::DeleteImportedXObject(acmepc);

            return 1;

            }

            cout << "Emitted XML to file worked fine." << std::endl;

            eXactML::XMLImporterBase::DeleteImportedXObject(acmepc);

            return 0;

            程序一

            type CDATA #REQUIRED

            speed CDATA #REQUIRED>

            type (IDE|EIDE|SCSI) "IDE"

            size CDATA #REQUIRED

            units (GB|TB) "GB">

            n CDATA #REQUIRED

            units CDATA #REQUIRED>

            n CDATA #REQUIRED

            units CDATA #REQUIRED>

            ACMEPC.DTD文件

            在ACMEPCXML_PARSER.Y中生成的YACC輸入和在ACMEPCXML_LEXER.L中生成的LEX輸入。所有的這些類和解析器都包含在C++中的ACMEPCXML的名字空間中。

            使用這個生成的通用解析器非常簡單,只需生成類ACMEPCXML::XMLIMPORTER的一個實例,然后調用類中的Initiliaze()這個初始化的成員函數,在把XML文件傳給ImportFromFile()這個程序函數。這個引入的類通過GetXObject()來發布這個樹形的根結點。這個基本的類在動態的返回給在ACMEPC.DTD文件中定義的XML上下文的ACMPEPC類。

            三. 生成的通用解析類的優點

            同一些其它的標準解析器或類相比,如DOM,SAX,自己生成的通用解析類主要由如下的幾個特點和優點。

            1. 最根本也是最重要的─解析的速度快。經過測試,根據XML模式生成的通用解析器,要比最快的DOM解析器速度要快三倍以上,而且內存的占用也很少。這主要是因為對于XML文件的輸入不需要經過有效性的檢查和判斷。這個工作早在由輸入文件生成YACC時,就已經做好和強制性的檢查。

            2. 生成的通用解析器能和其它的派生類非常好的結合在一起。而且不用象使用DOM一樣,生成一個DOM的數形結構,然后在對這些數據進行操作。通用解析器能直接的生成XML模式的派生類,這樣就省去了中間的步驟。當然,該解析類也能很好的和STL或MFC的類庫結合在一起

            3. 你能得到鏈接到你應用程序組件的所用源代碼。只要嚴格遵循符合GNU規范的FLEX和BISON工具的使用,生成的代碼就能夠在任何的操作系統上運行,從而很好的解決了跨平臺的問題。

            4. 最后也是最令人激動的一個優點是使用LEX和YACC可以方便的來操作和處理XML文件中的實體元素(ENTITY)。你可以在輸入文件中自動擴展實體的數量。XML中的實體也可以如C程序中的宏定義一樣,是C編譯器提前預處理。當你要處理大量的實體元素是,將非常有效。

            四. 總結

            由XML模式(SCHEMA)生成C++的類,作為解析器來解析XML的輸入文件是件非常令人激動的事,它不但能減少重復的編碼,更能提高你的效率。在不久的將來該項技術將會由長足的發展。

            五. 附該程序的所有源代碼(包括C++的類和DTD文件,XML文件

            xmlparser.zip

            posted on 2008-11-22 14:27 肥仔 閱讀(1383) 評論(1)  編輯 收藏 引用 所屬分類: XMLLEX & YACC

            評論

            # re: 用YACC提高XML在C++中的解析性能  回復  更多評論   

            少文件呢??
            2009-02-05 15:11 | ww
            久久亚洲私人国产精品| 国产精品久久久久久五月尺| 91精品国产综合久久久久久| 日韩亚洲欧美久久久www综合网 | 亚洲国产精品无码久久一线| 中文字幕久久精品无码| 久久精品国产亚洲沈樵| 久久无码一区二区三区少妇| 日韩av无码久久精品免费| 久久精品国产亚洲AV不卡| 色8久久人人97超碰香蕉987| 久久精品国产黑森林| 久久精品国产亚洲精品2020| 久久伊人五月天论坛| 久久精品国产清高在天天线| 开心久久婷婷综合中文字幕| 久久99精品久久久久久动态图| 久久人人爽人人爽AV片| 久久精品国产亚洲综合色| 久久精品国产日本波多野结衣| 国产A级毛片久久久精品毛片| 久久久久亚洲AV无码专区体验 | 狠狠综合久久AV一区二区三区| 99久久婷婷国产综合精品草原| 亚洲精品乱码久久久久久按摩 | 国产A三级久久精品| 亚洲国产成人久久一区WWW| 免费观看成人久久网免费观看| 亚洲精品美女久久777777| 日韩十八禁一区二区久久| 香港aa三级久久三级| 97久久久精品综合88久久| 欧洲人妻丰满av无码久久不卡| 久久综合伊人77777麻豆| 精品久久久久久无码免费| 91久久精品国产91性色也| 色综合久久综合网观看| 青青热久久综合网伊人| 国产精品欧美久久久久天天影视| 91久久国产视频| 免费一级欧美大片久久网|