Symbian學習筆記(15)
網上也有這方面的資料,建議參考:
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 <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三個函數中:
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通知觀察者“我處理完了,請拿走結果吧”。
【編輯推薦】