您的位置:首页 > 编程语言 > Java开发

Symbian学习笔记——解析XML文件(上)

2010-09-03 11:27 337 查看
今天想分享的是如何在Symbian平台上解析XML文件,不需要第三方的东西,Symbian已经为我们提供了这个类CParser。

网上也有这方面的资料,建议参考:
http://wiki.forum.nokia.com/index.php/How_to_parse_XML_file_using_CParser_class

不过,要注意的是Symbian中的CParser是基于SAX方式来解析的也就是说它是基于事件流方式,对于SAX,如果做过JAVA开发的一般不会陌生了。与DOM相比SAX方式在操作上会有点麻烦而且显得没那么好理解。

简要比较一下吧,DOM是将XML在内存中展开成一个树的模型,我们可以方便地访问它的每个子节点,可读可写。但是SAX呢?我们只能通过一个单向文本流去解析XML,在过程中有多个事件回调(开始某个元素处理、结束某个元素处理等等),它是单向只读的。

下面我们来详细说明一下如何实现吧。
首先,我们建立一个解析器派生于CActive,由它负责整个解析过程(因为这是一个异步操作)。




#include <xmlparser.h>


#include <xmlcontenthandler.h>




using namespace Xml;




class MXMLHandlerObserver


{


public:


    virtual void OnParseCompleted( TInt aError ) = 0;


};




class CXMLActiveParser : public CActive {


public:


    ~CXMLActiveParser();


    static CXMLActiveParser* NewL(MXMLHandlerObserver& aObserver,MContentHandler& aHandler);


    static CXMLActiveParser* NewLC(MXMLHandlerObserver& aObserver,MContentHandler& aHandler);




public:


    void StartL(const TDesC& aFileName);




private:


    CXMLActiveParser(MXMLHandlerObserver& aObserver,MContentHandler& aHandler);


    void ConstructL();




private:


    void RunL();


    void DoCancel();


    TInt RunError(TInt aError);




private:


    


    CParser*            iParser;


    HBufC8*             iBuffer;


    RFile               iFile;


    


    MContentHandler        *iHandler;


    MXMLHandlerObserver *iObserver;


 


    RFs                    iFs;


};


除了CActive所必需的东西以外,我们增加了 iParser 成员负责解析,iBuffer保存文件内容以供给iParser去解析,而iHandler是SAX所特有的回调处理类(后面详述),iObserver则是自定义的一个接口,其实是一个Notifer,就是在解析完成后调用它的OnParseCompleted方法。

实现的部分主要功能在Construct、Start和Run三个函数中:


void CXMLActiveParser::ConstructL() {    


    CActiveScheduler::Add( this); // Add to scheduler


    iParser = CParser::NewL( KXmlMimeType, *iHandler );    


    iFs.Connect();


}




void CXMLActiveParser::StartL(const TDesC& aFileName) {


    Cancel(); 


    


    User::LeaveIfError( iFile.Open( /*CCoeEnv::Static()->FsSession()*/iFs, aFileName,


            EFileRead ) );


    delete iBuffer;


    iBuffer = 0;


    


    iBuffer = HBufC8::NewL( KFileBufferSize );


    TPtr8 bufferPtr( iBuffer->Des() );


    iFile.Read( bufferPtr, KFileBufferSize, iStatus );


    SetActive();


  


    iParser->ParseBeginL();


}




void CXMLActiveParser::RunL() {


    if ( KErrNone == iStatus.Int() ){


        if ( iBuffer->Length() == 0){


            iParser->ParseEndL();


            iFile.Close();


            delete iBuffer;


            iBuffer = 0;


            


            iObserver->OnParseCompleted(KErrNone);


        }


        else {


            iParser->ParseL( *iBuffer );


            TPtr8 bufferPtr( iBuffer->Des() );


            iFile.Read( bufferPtr, KFileBufferSize, iStatus );


            SetActive();


        }


    }


    else {


        //error handler.


        iObserver->OnParseCompleted(iStatus.Int());


    }


}

注意CParser在NewL时告诉它文档类型是 _LIT8( KXmlMimeType, "text/xml" ) ,以及它需要的回调处理器是iHandler。然后在StartL时读入XML文件,准备解析。在RunL中如果未完成则开始解析,真到完成后则调用iObserver的onParseCompleted通知观察者“我处理完了,请拿走结果吧”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息