0
votes

I have a C++ program that uses xerces library to write data into an xml file. Can anyone help me out in parsing(reading) the attribute values from the xml file using the same xerces library?

I got the below program that is said to serve the purpose:

#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/util/XMLString.hpp>
#include <conio.h>
#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <iostream>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
using namespace std;
using namespace xercesc;


class ErnstSax2Handler : public DefaultHandler 
{
    public:
    ErnstSax2Handler(void);
    virtual ~ErnstSax2Handler(void);

    void startElement(
    const   XMLCh* const    uri,
    const   XMLCh* const    localname,
    const   XMLCh* const    qname,
    const   Attributes&     attrs
    );
    void endElement(
    const   XMLCh* const    uri,
    const   XMLCh* const    localname,
    const   XMLCh* const    qname
    );
    void characters(
    const   XMLCh* const    chars,
    const   XMLSize_t       length
    );

    void fatalError(const SAXParseException&);

    protected:
    // define variables to save the state
};

void ErnstSax2Handler::startElement(const   XMLCh* const    uri,
                    const   XMLCh* const    localname,
                    const   XMLCh* const    qname,
                    const   Attributes&     attrs)
{
    char* name = XMLString::transcode(localname);
    cout<<name;
    // ...
    XMLString::release(&name);
}
void ErnstSax2Handler::endElement(
            const   XMLCh* const    uri,
            const   XMLCh* const    localname,
            const   XMLCh* const    qname)
{
    char* name = XMLString::transcode(localname);

    //...
    XMLString::release(&name);
}
void ErnstSax2Handler::fatalError(const SAXParseException& exception)
{
    char* message = XMLString::transcode(exception.getMessage());
    cout << "Fatal Error: " << message
         << " at line: " << exception.getLineNumber()
         << endl;
    XMLString::release(&message);
}
void ErnstSax2Handler::characters(
const   XMLCh* const    chars,
const   XMLSize_t       length
)
{
 // This is called when the parser is reading text.
 // You will need to save what state you are in via
 // startElement / endElement.
 }


int main () {

    try {
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Error during initialization! :\n";
        cout << "Exception message is: \n"
         << message << "\n";
        XMLString::release(&message);
        return 1;
    }

    char* xmlFile = "test.xml";
    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
    parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);   // optional

    DefaultHandler* defaultHandler = new DefaultHandler();
    xercesc::ContentHandler* h  = new DefaultHandler();

    parser->setContentHandler(h);
    parser->setErrorHandler(defaultHandler);

    try {
        parser->parse(xmlFile);
    }
    catch (const XMLException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Exception message is: \n"
         << message << "\n";
        XMLString::release(&message);
        return -1;
    }
    catch (const SAXParseException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Exception message is: \n"
             << message << "\n";
        XMLString::release(&message);
        return -1;
    }
    catch (...) {
        cout << "Unexpected Exception \n" ;
        return -1;
    }    


//getch();
delete parser;
delete defaultHandler;
return 0;
}

But ended up getting a lot of errors like this:

error LNK2019: unresolved external symbol "__declspec(dllimport) public: static void __cdecl xercesc_3_1::XMLString::release(char * *,class xercesc_3_1::MemoryManager * const)" (_imp?release@XMLString@xercesc_3_1@@SAXPAPADQAVMemoryManager@2@@Z) referenced in function "public: virtual void __thiscall ErnstSax2Handler::startElement(wchar_t const * const,wchar_t const * const,wchar_t const * const,class xercesc_3_1::Attributes const &)" (?startElement@ErnstSax2Handler@@UAEXQB_W00ABVAttributes@xercesc_3_1@@@Z) XmlRead.obj error LNK2019: unresolved external symbol "__declspec(dllimport) public: static void __cdecl xercesc_3_1::XMLString::release(char * *,class xercesc_3_1::MemoryManager * const)" (_imp?release@XMLString@xercesc_3_1@@SAXPAPADQAVMemoryManager@2@@Z) referenced in function "public: virtual void __thiscall ErnstSax2Handler::startElement(wchar_t const * const,wchar_t const * const,wchar_t const * const,class xercesc_3_1::Attributes const &)" (?startElement@ErnstSax2Handler@@UAEXQB_W00ABVAttributes@xercesc_3_1@@@Z) XmlRead.obj .

Can anyone suggest me a different program or a fix to the above program?

1

1 Answers

0
votes

I had encountered the same error while working with Xerces Sax Parser. I was able to resolve the issue by specifying the additional dependencies properly. You need to specify Xerces(both library as well as the header)as additional dependencies in your project.This will hopefully solve the issue..

Also in your code,you have created the Default Handler,i.e

   DefaultHandler* defaultHandler = new DefaultHandler();
    xercesc::ContentHandler* h  = new DefaultHandler();

Instead you have to create the instance of your handler i.e

   DefaultHandler* defaultHandler = new ErnstSax2Handler();
    xercesc::ContentHandler* h  = new ErnstSax2Handler();

whenever the parser encounters the Start tag or content tag or end tag(or any other),the instance of your handler will be created and functions in your handler will be executed.

Useful Link: http://www.onlamp.com/pub/a/onlamp/2005/11/10/xerces_sax.html