×

Discussion Board

Results 1 to 8 of 8

Hybrid View

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    10

    Question SAX Xml Parsing - OnStartElement() not getting called!

    Hi,

    I referred this link (http://www.developer.nokia.com/Commu..._CParser_class) to get a xml parser implemented.

    Implemented the same in a new application.

    On calling "ParseL(data)", OnStartDocument() gets called but OnStartElement() never gets called.

    Instead, ParseEndL() gets called immediately.

    I checked for the xml data given as input, and it appears to be correct.

    Please help me on this. Should something more be specified in the application?

    I'm reading the file content at once without using an active object to read the file in chunks.

    Kindly help me with this issue
    Thanks.

  2. #2
    Nokia Developer Champion
    Join Date
    Jun 2008
    Location
    Noida,India
    Posts
    4,080

    Re: SAX Xml Parsing - OnStartElement() not getting called!

    Did you get any error code inside OnStartDocument(const RDocumentParameters& /*aDocParam*/,
    TInt aErrorCode )

    Also can you paste your implementation here.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    10

    Question Re: SAX Xml Parsing - OnStartElement() not getting called!

    Hi Vineet,

    Thanks for your reply.

    I checked for the error code value and it is "0".

    Please find my implementation for Xml Parsing below (its same as the one in wiki example, except with values filled for corresponding tag)

    Thanks.

    // --------------------------------------------------------------------------
    // XmlHandler.cpp
    //

    // 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(KNewLine, "\n" );
    //_LIT8(KSpace, " ");

    _LIT8( KXmlMimeType, "text/xml" );

    // METHODS DEFINITION
    EXPORT_C CXmlHandler* CXmlHandler::NewL()
    {
    CXmlHandler* self = CXmlHandler::NewLC();
    CleanupStack::Pop();
    return self;
    }

    EXPORT_C CXmlHandler* CXmlHandler::NewLC()
    {
    CXmlHandler* self = new ( ELeave ) CXmlHandler();
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }
    EXPORT_C CXmlHandler::~CXmlHandler()
    {
    Cancel();
    delete iParser;
    delete iBuffer;
    //delete controlList;
    //delete accessControl;
    //delete policyBlock;
    //delete iSecPolicy;
    }

    CXmlHandler::CXmlHandler()
    :CActive( EPriorityStandard ),
    iParser( 0 ),
    iState( EIdle )
    {
    CActiveScheduler::Add( this );
    }

    void CXmlHandler:oCancel()
    {
    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();
    }
    }
    }
    void CXmlHandler::ConstructL()
    {
    iParser = CParser::NewL( KXmlMimeType, *this );
    iBuffer = NULL;
    appList = NULL;
    controlList = NULL;//CControlList::NewL();
    accessControl= NULL;
    iSecPolicy = NULL;
    }
    EXPORT_C 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.
    #ifdef __DEBUG_SEC_POLICY
    TBuf<150> log;
    log.Copy(_L("CXmlHandler::StartParsingL starts"));
    CLogger::NewL()->Log(DEBUG, log);
    _LIT(KSecPolicy,"C:\\DATA\\others\\SecPolicy.txt");
    WriteToFile(aData, KSecPolicy);
    #endif

    RFile file;
    User::LeaveIfError( file.Open( CCoeEnv::Static()->FsSession(), aFileName,
    EFileRead ) );
    CleanupClosePushL( file );


    TInt size;
    User::LeaveIfError( file.Size( size ) );
    if(iBuffer)
    {
    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.
    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 if needed....
    }
    }

    void CXmlHandler::OnEndDocumentL( TInt aErrorCode )
    {

    if ( KErrNone == aErrorCode )
    {
    // Do something here if needed....
    }
    }

    void CXmlHandler::OnStartElementL( const RTagInfo& aElement,
    const RAttributeArray& aAttributes, TInt aErrorCode )
    {
    #ifdef __DEBUG_SEC_POLICY
    TBuf<100> log;
    log.Copy(_L("CXmlHandler::OnStartElementL Starts"));
    CLogger::NewL()->Log(DEBUG, log);
    #endif

    if ( KErrNone == aErrorCode )
    {
    #ifdef __DEBUG_SEC_POLICY
    TBuf<50> errorCode;
    errorCode.AppendNum(aErrorCode);
    log.Copy(_L("CXmlHandler::OnStartElementL Starts"));
    log.Append(errorCode);
    CLogger::NewL()->Log(DEBUG, log);
    #endif
    tag = aElement.LocalName().DesC();

    TBuf8<20> name;
    TBuf8<20> value;
    TInt attrVal;
    TLex8 numConvert;

    if (tag.Compare(KSECURITY_POLICY_TAG) == 0)
    {
    //some code here
    }
    }
    }

    void CXmlHandler::OnEndElementL( const RTagInfo &aElement, TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
    {

    tag = aElement.LocalName().DesC();

    if (tag.Compare(KPOLICY_BLOCK_TAG) == 0)
    {
    if (iSecPolicy != NULL)
    {
    if (policyBlock != NULL)
    {
    iSecPolicy->SetPolicyBlock(policyBlock);
    //ShowVal();
    }
    }
    }
    else if (tag.Compare(KACCESS_CONTROL_TAG) == 0)
    {
    AddToRCtrlPolicyBlock(accessControl);
    }
    else if(tag.Compare(KCONTROL_LIST_TAG) == 0)
    {
    if(accessControl && controlList)
    {
    AddCtrlListToAccessCtrl(controlList, accessControl);
    }
    }
    else if(tag.Compare(KAPP_LIST_TAG) == 0) //End of a single applist node
    {
    //RPointerArray<HBufC8> appListLoc = appList->GetApps();
    //TInt count = appListLoc.Count();

    if (appList && controlList)
    {
    AddAppListToControlList(appList, controlList);
    }
    }
    }
    }

    void CXmlHandler::OnContentL( const TDesC8 &aBytes, TInt aErrorCode )
    {
    if ( KErrNone == aErrorCode )
    {

    HBufC8* valbuffer = NULL;
    //Add apps item list to the AppList array
    if(tag.Compare(KITEM_TAG) == 0)
    {
    //Copy value into a local buffer
    valbuffer = HBufC8::NewLC(aBytes.Length() + 1);
    TPtr8 valbufPtr(valbuffer->Des());
    valbufPtr.Copy(aBytes);
    valbufPtr.TrimAll();

    if((valbufPtr.Compare(KNewLine) != 0) && (valbufPtr.Length() > 0))
    {//Add to the applist array
    appList->AddToAppList(valbuffer);
    }

    CleanupStack::PopAndDestroy(); // destroy the local buffer
    }
    }
    }

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

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

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

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

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

    void CXmlHandler::OnError( TInt aErrorCode )
    {

    }

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

  4. #4
    Nokia Developer Champion
    Join Date
    Jun 2008
    Location
    Noida,India
    Posts
    4,080

    Re: SAX Xml Parsing - OnStartElement() not getting called!

    I think iBuffer becomes empty or remains empty that is why ParseEndL() gets called, signifying that the end of file has been reached. So you might want to check that length of iBuffer is greater then zero, may be you can put a check for it , i.e if(iBuffer->Length()>0)

  5. #5
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,738

    Re: SAX Xml Parsing - OnStartElement() not getting called!

    You may want to check if OnError get invoked, and its error code of course. In fact I can not recall if the other methods ever get a real error code.

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    10

    Re: SAX Xml Parsing - OnStartElement() not getting called!

    Thank you for the reply..

    I was able to get it working when I changed the encoding value in the xml to "utf-8"

    But the actual data had encoding = "utf-16".

    Actually, I get the xml data to be parsed, from the server, upon request.

    I store this xml content value in a HBufC8 buffer and then give it for parsing.

    What change should I make to get it working "Utf-16" encoding?

    Please help me with this.

    Thanks.

  7. #7
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,738

    Re: SAX Xml Parsing - OnStartElement() not getting called!

    The standard Symbian API-s do not support UTF-16.
    On the other hand, user-presentable strings are handled in 16-bit Unicode format (UCS-2). The similarities and differences are described on Wikipedia for example: http://en.wikipedia.org/wiki/UTF-16
    So, treating UTF-16 data as simple UCS-2 may work.
    An approach which could be tested:
    1) you probably get the actual data in a 8-bit descriptor (as it comes from a server), so the bytes should be paired into a 16-bit descriptor
    2) a 16-bit descriptor can be UTF-8 encoded with CnvUtfConveter class
    3) the UTF-8 encoded descriptor can be fed to the parser
    4) whatever 8-bit descriptor comes back from the parser is actually UTF-8 encoded, but CnvUtfConverter can convert in both directions. At the end you will theoretically get back UTF-16 encoded content from elements/attributes, and you can just pretend that they are simple UCS-2 strings and try displaying them which will work most of the time.
    Problems which may arise:
    - byte order: it is easy, try the other one
    - if the XML document has a standard head with encoding specification, the parser may look strange if the encoding says UTF-16, this issue can be handled via explicitly checking this part and replacing if necessary
    Code:
    "TDes8 input8;" // whatever input you have at the beginning
    TPtr16 inputUCS2(reinterpret_cast<TUint16*>(&input8[0]),input8.Length()/2,input8.Length()/2);
    HBufC8 *inputUTF8=CnvUtfConverter::ConvertFromUnicodeToUtf8L(inputUCS2);
    could be the first try, and pass *inputUTF8 to the XML parser.
    But it is actually better to check it first with your own eyes. If it is a complete mess, then ByteOrder::Swap16 can swap the bytes for you
    Code:
    for(TInt i=0;i<inputUCS2.Length();i++)inputUCS2[i]=ByteOrder::Swap16(inputUCS2[i]);

  8. #8
    Registered User
    Join Date
    May 2012
    Posts
    10

    Re: SAX Xml Parsing - OnStartElement() not getting called!

    Thank you very much..

    Will definitely try this..

Similar Threads

  1. Reg:parsing
    By moulii in forum Symbian
    Replies: 43
    Last Post: 2010-08-31, 17:04
  2. Reg:parsing
    By ranjini in forum Symbian
    Replies: 8
    Last Post: 2010-08-09, 13:12
  3. Replies: 3
    Last Post: 2009-06-01, 09:43
  4. Replies: 4
    Last Post: 2008-03-05, 09:30

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×