Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

如何使用CParser类来解析XML文件

From Wiki
Jump to: navigation, search
Article Metadata

文章
翻译:
hoolee
最后由 hamishwillee 在 22 Dec 2011 编辑


下列示例中演示了如何使用Symbian OS C++类CParser来解析XML文件。CParser是一个基于SAX(Simple API for XML)的XML解析器。

他使用一个活动对象读取XML文件流(使用CXmlHandler::StartParsingWithAoL()方法),在每个chunk中都传递buffer流到XML解析器。当XML解析器找到元素后,它就调用相应的回调函数,例如CXmlHandler::OnStartElementL()CXmlHandler::OnEndElementL().

要使用CParser类,需要在mmp文件中添加XmlFramework.lib,更多关于CParser类的解释,请参考本文相关链接


Contents

XmlHandler.h

#ifndef __XMLHANDLER_H__
#define __XMLHANDLER_H__
 
// INCLUDE FILES
#include <e32base.h>
#include <f32file.h> //Link against efsrv.lib
#include <xml\contenthandler.h> // for MContentHandler
#include <xml\parser.h> // for CParser
 
// CLASS DECLARATION
 
using namespace Xml;
 
class CXmlHandler: public CActive, MContentHandler
{
 
public: // Constructors and destructor
 
static CXmlHandler* NewL();
 
static CXmlHandler* NewLC();
 
virtual ~CXmlHandler();
 
public: // Public methods
 
void StartParsingWithAoL( const TDesC& aFileName );
 
private: // Constructors
 
CXmlHandler();
 
void ConstructL();
 
private: // from CActive
 
void DoCancel();
 
void RunL();
 
private: // from MContentHandler
 
void OnStartDocumentL( const RDocumentParameters &aDocParam,
TInt aErrorCode );
 
void OnEndDocumentL( TInt aErrorCode );
 
void OnStartElementL( const RTagInfo &aElement,
const RAttributeArray &aAttributes, TInt aErrorCode );
 
void OnEndElementL( const RTagInfo &aElement, TInt aErrorCode );
 
void OnContentL( const TDesC8 &aBytes, TInt aErrorCode );
 
void OnStartPrefixMappingL( const RString &aPrefix, const RString &aUri,
TInt aErrorCode );
 
void OnEndPrefixMappingL( const RString &aPrefix, TInt aErrorCode );
 
void OnIgnorableWhiteSpaceL( const TDesC8 &aBytes, TInt aErrorCode );
 
void OnSkippedEntityL( const RString &aName, TInt aErrorCode );
 
void OnProcessingInstructionL( const TDesC8 &aTarget, const TDesC8 &aData,
TInt aErrorCode);
 
void OnError( TInt aErrorCode );
 
TAny *GetExtendedInterface( const TInt32 aUid );
 
private: // Private data
 
CParser* iParser;
HBufC8* iBuffer;
RFile iFile;
 
};
 
#endif /* __XMLHANDLER_H__ */


XmlHandler.cpp

// INCLUDE FILES
#include <coemain.h>
#include "XmlHandler.h"
 
// CONSTANTS
const TInt KFileBufferSize = 1024; // buffer size for file reading
_LIT8( KXmlMimeType, "text/xml" );
 
// METHODS DEFINITION
 
CXmlHandler* CXmlHandler::NewL()
{
CXmlHandler* self = CXmlHandler::NewLC();
CleanupStack::Pop();
return self;
}
 
CXmlHandler* CXmlHandler::NewLC()
{
CXmlHandler* self = new ( ELeave ) CXmlHandler();
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
 
CXmlHandler::~CXmlHandler()
{
Cancel();
delete iParser;
delete iBuffer;
}
 
CXmlHandler::CXmlHandler()
:CActive( EPriorityStandard )
{
CActiveScheduler::Add( this );
}
 
void CXmlHandler::DoCancel()
{
iParser->ParseEndL();
iFile.Close();
delete iBuffer;
iBuffer = 0;
}
 
void CXmlHandler::RunL()
{
if ( KErrNone == iStatus.Int() )
{
// If the buffer length is zero, it means if we have reached
// the end of the file.
if ( iBuffer->Length() == 0)
{
iParser->ParseEndL();
iFile.Close();
delete iBuffer;
iBuffer = 0;
}
 
// Otherwise, we continue reading the next chunk of the XML file.
else
{
// Parse the next "part" of the XML document.
iParser->ParseL( *iBuffer );
 
// Read the next chunk of the file.
TPtr8 bufferPtr( iBuffer->Des() );
iFile.Read( bufferPtr, KFileBufferSize, iStatus );
 
// Don't forget to call this... :)
SetActive();
}
}
else
{
// Do something if error happens.
}
}
 
void CXmlHandler::ConstructL()
{
iParser = CParser::NewL( KXmlMimeType, *this );
}
 
void CXmlHandler::StartParsingWithAoL( const TDesC& aFileName )
{
// Remember to cancel any outstanding request first.
if ( IsActive() )
{
Cancel();
}
 
User::LeaveIfError( iFile.Open( CCoeEnv::Static()->FsSession(), aFileName,
EFileRead ) );
 
// Create a buffer to store the file content.
// Note that this method uses active object to read the file.
// So we have to call SetActive() at the end. Then we call CParser::ParseL()
// in RunL() method.
delete iBuffer;
iBuffer = 0;
iBuffer = HBufC8::NewL( KFileBufferSize );
TPtr8 bufferPtr( iBuffer->Des() );
iFile.Read( bufferPtr, KFileBufferSize, iStatus );
SetActive();
 
// Tell the parser that we are about to parse a XML document.
iParser->ParseBeginL();
}
 
void CXmlHandler::OnStartDocumentL( const RDocumentParameters& /*aDocParam*/,
TInt aErrorCode )
{
if ( KErrNone == aErrorCode )
{
// Do something here when the parser at the start of the document.
}
else
{
// Do something if error happens.
}
}
 
void CXmlHandler::OnEndDocumentL( TInt aErrorCode )
{
if ( KErrNone == aErrorCode )
{
// Do something here when the parser reaches the end of the document.
}
}
 
void CXmlHandler::OnStartElementL( const RTagInfo& aElement,
const RAttributeArray& /*aAttributes*/, TInt aErrorCode )
{
if ( KErrNone == aErrorCode )
{
// Found start of an element, for example: "<tag>"
// The name of the element is stored in aElement.LocalName().DesC().
 
// Do something with the start of an element.
}
else
{
// Do something if error happens.
}
}
 
void CXmlHandler::OnEndElementL( const RTagInfo &aElement, TInt aErrorCode )
{
if ( KErrNone == aErrorCode )
{
// Found the end of an element, for example: "</tag>"
// The name of the element is stored in aElement.LocalName().DesC().
 
// Do something with the end of an element.
}
else
{
// Do something if error happens.
}
}
 
void CXmlHandler::OnContentL( const TDesC8 &aBytes, TInt aErrorCode )
{
if ( KErrNone == aErrorCode )
{
// aBytes stored the value of the parsed contents.
}
else
{
// Display error messages here.
}
}
 
void CXmlHandler::OnStartPrefixMappingL( const RString& /*aPrefix*/,
const RString& /*aUri*/, TInt aErrorCode )
{
}
 
void CXmlHandler::OnEndPrefixMappingL( const RString& /*aPrefix*/,
TInt aErrorCode )
{
}
 
void CXmlHandler::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/,
TInt aErrorCode )
{
}
 
void CXmlHandler::OnSkippedEntityL( const RString& /*aName*/,
TInt aErrorCode )
{
}
 
void CXmlHandler::OnProcessingInstructionL( const TDesC8& /*aTarget*/,
const TDesC8& /*aData*/, TInt aErrorCode )
{
}
 
void CXmlHandler::OnError( TInt aErrorCode )
{
// Do something if error happens.
}
 
TAny* CXmlHandler::GetExtendedInterface( const TInt32 /*aUid*/ )
{
return 0;
}

下载示例

相关链接

This page was last modified on 22 December 2011, at 04:46.
172 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×