Symbian学习笔记(15) - 解析XML文件(上)
来源:互联网 发布:qq炫舞mac版下载 编辑:程序博客网 时间:2024/05/19 13:17
我曾在前面介绍过一个可用于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,由它负责整个解析过程(因为这是一个异步操作)。
除了CActive所必需的东西以外,我们增加了 iParser 成员负责解析,iBuffer保存文件内容以供给iParser去解析,而iHandler是SAX所特有的回调处理类(后面详述),iObserver则是自定义的一个接口,其实是一个Notifer,就是在解析完成后调用它的OnParseCompleted方法。
实现的部分主要功能在Construct、Start和Run三个函数中:
注意CParser在NewL时告诉它文档类型是 _LIT8( KXmlMimeType, "text/xml" ) ,以及它需要的回调处理器是iHandler。然后在StartL时读入XML文件,准备解析。在RunL中如果未完成则开始解析,真到完成后则调用iObserver的onParseCompleted通知观察者“我处理完了,请拿走结果吧”。
网上也有这方面的资料,建议参考:
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;
};
#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());
}
}
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通知观察者“我处理完了,请拿走结果吧”。
- Symbian学习笔记(15) - 解析XML文件(上)
- Symbian学习笔记(15) - 解析XML文件(上)
- Symbian学习笔记——解析XML文件(上)
- Symbian学习笔记(16) - 解析XML文件(下)
- Symbian学习笔记(16) - 解析XML文件(下)
- Symbian学习笔记——解析XML文件(下)
- Symbian——解析XML文件
- Symbian——解析XML文件
- glib 学习笔记,解析xml文件
- Ant学习笔记(解析build.xml文件)
- 【Android学习笔记】XmlResourceParser解析xml文件
- symbian解析XML学习之路
- xml&dom_sax_dom4j学习笔记(一)SAX解析XML文件
- Android学习笔记-Xml文件解析之PULL解析实战
- symbian XML 解析
- Symbian解析XML文档
- Symbian XML解析
- symbian 解析XML
- RMI 与 RMIC 命令 理论部分
- java实现多态性二
- STL序列容器的存储连续性
- Oral English Course Note(1)
- 爱!智!慧!
- Symbian学习笔记(15) - 解析XML文件(上)
- C#反射学习
- mysql 常见出错号码解释 mysql error number
- 泛型编程在非C++语言中的实现之探讨
- 关于用visual stdio设计smartphone全屏应用程序
- SqlServer,Access,Oracle连接数据库的方法
- dbms_advisor.tune_mview不能用
- collate chinese_prc_ci_as null 是什么意思
- SQL中合并多行记录的方法总汇