Categories: Symbian C++ | How To | Code Examples | XML | Files/Data
This page was last modified 20:08, 15 December 2007.
How to parse XML file using CParser class
From Forum Nokia Wiki
The following example shows how to parse XML file using Symbian OS C++ class, CParser. CParser is basically a SAX (Simple API for XML)-based XML parser.
It uses an active object to read the XML file chunk by chunk (see CXmlHandler::StartParsingWithAoL() method). On each chunk, it passes the buffer to the XML parser. When the XML parser finds an element, it calls the respective callback functions, for example CXmlHandler::OnStartElementL() or CXmlHandler::OnEndElementL().
To use CParser class, the XmlFramework.lib has to be included in the .mmp file. For more information about CParser, please visit some links at the end of this page.
XmlHandler.h
#ifndef __XMLHANDLER_H__ #define __XMLHANDLER_H__ // INCLUDE FILES #include <e32base.h> #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 <f32file.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; }
See Also
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| how to get current drive? | sumn79 | General Symbian C++ | 4 | 2004-09-08 18:26 |
| download/upload xml from-to server in j2me | freezenik | Mobile Java Networking & Messaging & Security | 0 | 2005-01-26 05:00 |
| Midlet not connecting to Internet | kumudranjan_19 | Mobile Java General | 6 | 2005-08-16 08:18 |
| 发现一个命名空间的问题 | shitou514 | Symbian | 2 | 2008-07-16 11:02 |
| Application j2mw for Motorola | chia_84 | Mobile Java General | 8 | 2008-06-17 12:46 |
