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

我曾在前面介绍过一个 可用于BREW环境下的XML Parser,今天想分享的是如何在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:
virtualvoidOnParseCompleted(TIntaError)=0;
}
;

class CXMLActiveParser: public CActive ... {
public:
~CXMLActiveParser();
staticCXMLActiveParser*NewL(MXMLHandlerObserver&aObserver,MContentHandler&aHandler);
staticCXMLActiveParser*NewLC(MXMLHandlerObserver&aObserver,MContentHandler&aHandler);

public:
voidStartL(constTDesC&aFileName);

private:
CXMLActiveParser(MXMLHandlerObserver
&aObserver,MContentHandler&aHandler);
voidConstructL();

private:
voidRunL();
voidDoCancel();
TIntRunError(TIntaError);

private:

CParser
*iParser;
HBufC8
*iBuffer;
RFileiFile;

MContentHandler
*iHandler;
MXMLHandlerObserver
*iObserver;

RFsiFs;
}
;

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

实现的部分主要功能在Construct、Start和Run三个函数中:
void CXMLActiveParser::ConstructL() ... {
CActiveScheduler::Add(
this);//Addtoscheduler
iParser=CParser::NewL(KXmlMimeType,*iHandler);
iFs.Connect();
}


void CXMLActiveParser::StartL( const TDesC & aFileName) ... {
Cancel();

User::LeaveIfError(iFile.Open(
/**//*CCoeEnv::Static()->FsSession()*/iFs,aFileName,
EFileRead));
deleteiBuffer;
iBuffer
=0;

iBuffer
=HBufC8::NewL(KFileBufferSize);
TPtr8bufferPtr(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();
deleteiBuffer;
iBuffer
=0;

iObserver
->OnParseCompleted(KErrNone);
}

else...{
iParser
->ParseL(*iBuffer);
TPtr8bufferPtr(iBuffer
->Des());
iFile.Read(bufferPtr,KFileBufferSize,iStatus);
SetActive();
}

}

else...{
//errorhandler.
iObserver->OnParseCompleted(iStatus.Int());
}

}

注意CParser在NewL时告诉它文档类型是 _LIT8( KXmlMimeType, "text/xml" ) ,以及它需要的回调处理器是iHandler。然后在StartL时读入XML文件,准备解析。在RunL中如果未完成则开始解析,真到完成后则调用iObserver的onParseCompleted通知观察者“我处理完了,请拿走结果吧”。

你可能感兴趣的:(xml,PHP,brew,Symbian,Nokia)