How to parse XML file using CParser class


Reviewer Approved    
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.

Contents
[hide]
 1 XmlHandler.h
 2 XmlHandler.cpp
 3 download example
 4 See Also

[edit] 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__ */

[edit] 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;
    }
[edit] download example
 myxmlparser.zip

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值