⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlhandler.cpp

📁 symbian http/post引擎 xml引擎 支持IAP设置
💻 CPP
字号:
// --------------------------------------------------------------------------
// XmlHandler.cpp
//
// Copyright 2007, Antony Pranata
// http://www.antonypranata.com
//
// Example how to parse XML file using SAX on Symbian OS.
//
// There are two methods to parse XML document, i.e.;
//   - StartParsingL() -> parse XML document without active object.
//     The whole file content is read at once. It is simple, but suitable
//     for relatively small file only.
//   - StartParsingWithAoL() -> parse XML document with active object.
// --------------------------------------------------------------------------

// INCLUDE FILES
#include <coemain.h>
#include <f32file.h>
#include "XmlHandler.h"

// CONSTANTS
const TInt KBufferSize     = 1024; // buffer size to store the result of
                                   // XML parsing -> the actual buffer size
                                   // can expand if needed (see AppendText())
                                   
const TInt KFileBufferSize = 1024; // buffer size for file reading

const TInt KOverheadLen    = 4; // length of (KOpeningTag + KClosingTag
                                //            + KSlash + KEndOfLine)

_LIT(KOpeningTag, "<" );
_LIT(KClosingTag, ">" );
_LIT(KSlash,      "/" );
_LIT(KEndOfLine,  "\f" ); // CEikEdwin uses '\f' as EOF mark.

_LIT8( KXmlMimeType, "text/xml" );

// METHODS DEFINITION

// --------------------------------------------------------------------------

CXmlHandler* CXmlHandler::NewL( MXmlHandlerObserver& aObserver )
    {
    CXmlHandler* self = CXmlHandler::NewLC( aObserver );
    CleanupStack::Pop();
    return self;
    }

// --------------------------------------------------------------------------

CXmlHandler* CXmlHandler::NewLC( MXmlHandlerObserver& aObserver )
    {
    CXmlHandler* self = new ( ELeave ) CXmlHandler( aObserver );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

// --------------------------------------------------------------------------

CXmlHandler::~CXmlHandler()
    {
    Cancel();
    delete iParser;
    delete iDisplayResult;
    delete iBuffer;
    }

// --------------------------------------------------------------------------

CXmlHandler::CXmlHandler( MXmlHandlerObserver& aObserver )
    :CActive( EPriorityStandard ),
    iObserver( aObserver ),
    iParser( 0 ),
    iDisplayResult( 0 ),
    iState( EIdle )
    {
    CActiveScheduler::Add( this );
    }

// --------------------------------------------------------------------------

void CXmlHandler::DoCancel()
    {
    iParser->ParseEndL();
    iFile.Close();
    delete iBuffer;
    iBuffer = 0;
    }

// --------------------------------------------------------------------------

void CXmlHandler::RunL()
    {
    if ( KErrNone == iStatus.Int() )
        {
        // If the buffe 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
        {
        iObserver.OnParseCompleted( iStatus.Int() );
        }
    }

// --------------------------------------------------------------------------

void CXmlHandler::ConstructL()
    {
    iParser = CParser::NewL( KXmlMimeType, *this );
    iDisplayResult = HBufC::NewL( KBufferSize );
    }

// --------------------------------------------------------------------------
   
void CXmlHandler::StartParsingL( const TDesC& aFileName )
    {
    // Read the whole content of aFileName into iBuffer.
    // IMPORTANT: This example reads the whole content within
    // one-shot for simplicity reason.
    // In reality, you have to read it chunk by chunk
    // using active object so that your application doesn't block.
    RFile file;
    User::LeaveIfError( file.Open( CCoeEnv::Static()->FsSession(), aFileName,
        EFileRead ) );
    CleanupClosePushL( file );
    
    iDisplayResult->Des().Zero();
    TInt size;
    User::LeaveIfError( file.Size( size ) );
    delete iBuffer;
    iBuffer = 0;
    iBuffer = HBufC8::NewL( size );
    TPtr8 bufferPtr( iBuffer->Des() );
    User::LeaveIfError( file.Read( bufferPtr ) );
    
    CleanupStack::PopAndDestroy(); // file
    
    // Now, we have the whole file content in iBuffer.
    // We are ready to parse the XML content.
    iParser->ParseBeginL();
    iParser->ParseL( *iBuffer );
    
    // Since we read the whole file contents within one-shot,
    // we can call ParseEndL() right after calling ParseL().
    iParser->ParseEndL();
    }

// --------------------------------------------------------------------------
   
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.
    iDisplayResult->Des().Zero();
    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 )
    {
    // Display message to the screen stating that this is the starting of
    // XML document.
    _LIT( KOnStartDocumentL, "*** OnStartDocumentL ***\f" );
    AppendText( KOnStartDocumentL );
    
    if ( KErrNone == aErrorCode )
        {
        // Do something if needed....
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }

// --------------------------------------------------------------------------
    
void CXmlHandler::OnEndDocumentL( TInt aErrorCode )
    {
    // Display message to the screen stating that this is the starting of
    // XML document.
    _LIT( KOnEndDocumentL, "*** OnEndDocumentL ***\f" );
    AppendText( KOnEndDocumentL );
    
    if ( KErrNone == aErrorCode )
        {
        // Do something here if needed....
        }
        
    iObserver.OnParseCompleted( aErrorCode );
    }

// --------------------------------------------------------------------------

void CXmlHandler::OnStartElementL( const RTagInfo& aElement,
        const RAttributeArray& /*aAttributes*/, TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // If we find the start of an element, we write to the screen,
        // for example: "<tag>"
        AppendTag( aElement.LocalName().DesC(), EFalse );
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }
        
// --------------------------------------------------------------------------

void CXmlHandler::OnEndElementL( const RTagInfo &aElement, TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // If we find the end of an element, we write it to the screen,
        // for example: "</tag>"
        AppendTag( aElement.LocalName().DesC(), ETrue );
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }
    
// --------------------------------------------------------------------------

void CXmlHandler::OnContentL( const TDesC8 &aBytes, TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // Display aBytes on the screen.
        // Before we can display it, we have to convert the content
        // from TDesC8 to TDesC16.
        HBufC* buffer = HBufC::NewLC( aBytes.Length() + 1 );
        TPtr bufferPtr( buffer->Des() );
        bufferPtr.Copy( aBytes );
        AppendText( *buffer );
        CleanupStack::PopAndDestroy(); // buffer
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }
    
// --------------------------------------------------------------------------

void CXmlHandler::OnStartPrefixMappingL( const RString& /*aPrefix*/,
        const RString& /*aUri*/, TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // Do something here...
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }
        
// --------------------------------------------------------------------------

void CXmlHandler::OnEndPrefixMappingL( const RString& /*aPrefix*/,
        TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // Do something here...
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }
    
// --------------------------------------------------------------------------

void CXmlHandler::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/,
        TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // Do something here...
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }
    
// --------------------------------------------------------------------------

void CXmlHandler::OnSkippedEntityL( const RString& /*aName*/,
        TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // Do something here...
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }

// --------------------------------------------------------------------------

void CXmlHandler::OnProcessingInstructionL( const TDesC8& /*aTarget*/,
        const TDesC8& /*aData*/, TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
        {
        // Do something here...
        }
    else
        {
        iObserver.OnParseCompleted( aErrorCode );
        }
    }

// --------------------------------------------------------------------------

void CXmlHandler::OnError( TInt aErrorCode )
    {
    _LIT( KErrorMessage, "*** OnError ***\f" );
    AppendText( KErrorMessage );
    iObserver.OnParseCompleted( aErrorCode );
    }

// --------------------------------------------------------------------------

TAny* CXmlHandler::GetExtendedInterface( const TInt32 /*aUid*/ )
    {
    return 0;
    }

// --------------------------------------------------------------------------

void CXmlHandler::AppendText( const TDesC& aText )
    {
    TPtr displayResultPtr( iDisplayResult->Des() );
    if ( displayResultPtr.Length() + aText.Length() > displayResultPtr.MaxLength() )
        {
        iDisplayResult = iDisplayResult->ReAllocL( displayResultPtr.MaxLength()
            + KBufferSize );
        displayResultPtr.Set( iDisplayResult->Des() );
        }    
    displayResultPtr.Append( aText );
    }

// --------------------------------------------------------------------------

void CXmlHandler::AppendTag( const TDesC8& aTag, TBool aIsClosingTag )
    {
    // Instantiate buffer to display tag information.
    HBufC* buffer = HBufC::NewLC( aTag.Length()
        + ( ( aIsClosingTag ) ? KOverheadLen : KOverheadLen - 1 ) );
    TPtr bufferPtr( buffer->Des() );
        
    // Convert tag name from TDesC8 to TDesC16.
    bufferPtr.Copy( aTag );
        
    // Add opening tag.
    if ( aIsClosingTag )
        {
        bufferPtr.Insert( 0, KSlash );
        }
    bufferPtr.Insert( 0, KOpeningTag );
        
    // Add closing tag.
    bufferPtr.Append( KClosingTag );
    bufferPtr.Append( KEndOfLine );
        
    // Add to the result text and then destroy it.
    AppendText( *buffer );
    CleanupStack::PopAndDestroy(); // buffer
    }

// End of File

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -