Parse xml file based on XPATH using xercesc 3.x

Post date: Jul 5, 2011 12:31:29 PM

#include <xercesc/util/PlatformUtils.hpp>

#include <xercesc/util/XMLString.hpp>

#include <xercesc/dom/DOM.hpp>

#include <xercesc/util/OutOfMemoryException.hpp>

#include <xercesc/framework/MemBufFormatTarget.hpp>

#include <xercesc/framework/StdOutFormatTarget.hpp>

#include <xercesc/framework/MemBufInputSource.hpp>

#include <xercesc/parsers/XercesDOMParser.hpp>

#include <string>

#if defined(XERCES_NEW_IOSTREAMS)

#include <iostream>

#else

#include <iostream.h>

#endif

XERCES_CPP_NAMESPACE_USE

class XStr

{

        public:

                XStr(const char* const toTranscode)

                {

                        fUnicodeForm = XMLString::transcode(toTranscode);

                }

                ~XStr()

                {

                        XMLString::release(&fUnicodeForm);

                }

                const XMLCh* unicodeForm() const

                {

                        return fUnicodeForm;

                }

        private:

                XMLCh*   fUnicodeForm;

};

#define X(str) XStr(str).unicodeForm()

std::string xml_string =

"<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><corporation xmlns='com:cmcc:corporation' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='com:cmcc:corporation corporation.xsd'><eid>100000</eid><basic><corp_name>abcd</corp_name><corp_code/><c0/><short_name/><calling_code/><legal_representative/><address/><zip/><telephone/><fax/><contact/><proportion_code/><logo_crc/><employee_portrait_crc/><group_portrait_crc/><createtime/><opentime/><province_code/><vgop_code/><org_version/><source_code/><client_dept_version/><version_id/><contact_mp/></basic><rules><order_flag/><demo_flag/><useroperate_limit/><emp_portrait_flag/><iplmt/><dept_auth_switch/><sms_block/><sms_begin/><sms_end/><edit_status/><expire_time/></rules><accounts><scale_code/><customer_manager/><manager_phone/><deposit_bank/><bank_accounts/><password_paper_id/><group_code/><sms_code/><meeting_code/><fee_code/><cycle_code/><sharedisk_code/><sp_status/><updatetime/></accounts></corporation>";

std::string basic_string = "<basic><test>good</test></basic>";

int main(int argC, char*argV[])

{

        // Initialize the XML4C2 system.

        try

        {

                XMLPlatformUtils::Initialize();

        }

        catch(const XMLException& toCatch)

        {

                char *pMsg = XMLString::transcode(toCatch.getMessage());

                XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"

                        << "  Exception message:"

                        << pMsg;

                XMLString::release(&pMsg);

                return 1;

        }

        DOMImplementation* impl =  DOMImplementationRegistry::getDOMImplementation(X("LS"));

        DOMLSSerializer*   theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer();

        DOMLSOutput       *theOutputDesc = ((DOMImplementationLS*)impl)->createLSOutput();

        MemBufFormatTarget* target = new MemBufFormatTarget();

        theOutputDesc->setByteStream(target);

        if (impl != NULL)

        {

                try

                {

                        XercesDOMParser* parser = new XercesDOMParser();

                        MemBufInputSource* xml_mem = new MemBufInputSource(

                                        (const XMLByte* )xml_string.c_str(),

                                        xml_string.length(),

                                        "xml",

                                        false);

                        parser->parse( *xml_mem );

                        DOMDocument* xml_doc = parser->getDocument();

                        DOMElement* xml_root = xml_doc->getDocumentElement();

                        if (NULL == xml_root)

                        {

                                std::cout<< "Empty XML document!\n";

                                exit(1);

                        }

                        std::cout<< XMLString::transcode(theSerializer->writeToString((DOMNode* )xml_root))<< std::endl;

                  

                        DOMXPathNSResolver* resolver = xml_doc->createNSResolver(xml_root);

                        DOMXPathResult* result = xml_doc->evaluate(

                                        X("/corporation/basic"),

                                        xml_root,

                                        resolver,

                                        DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,

                                        NULL);

                        result->snapshotItem(0);

                        DOMNode*  curentNode = result->getNodeValue();

                        DOMNode*  prevNode = curentNode->getParentNode();

                        theSerializer->write(curentNode, theOutputDesc);

                        std::cout<< target->getRawBuffer()<< std::endl;

                        //replace the basic child

                        MemBufInputSource* basic_mem = new MemBufInputSource(

                                        (const XMLByte* )basic_string.c_str(),

                                        basic_string.length(),

                                        "basic",

                                        false);

                        parser->parse( *basic_mem );

                        DOMDocument* basic_doc = parser->getDocument();

                        DOMElement* basic_root = basic_doc->getDocumentElement();

                        DOMNode* newnode = xml_doc->importNode((DOMNode* )basic_root, true);

                        prevNode->replaceChild(newnode, curentNode);

                  

                        std::cout<< XMLString::transcode(theSerializer->writeToString((DOMNode* )xml_root))<< std::endl;

                        delete basic_mem;

                        delete xml_mem;

                        delete target;

                        delete parser;

                        result->release();

                        resolver->release();

                        theOutputDesc->release();

                        theSerializer->release();

                }

                catch(const OutOfMemoryException&)

                {

                        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;

                }

                catch (const DOMException& e)

                {

                        XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;

                }

                catch (...)

                {

                        XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;

                }

        }

        else

        {

                XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;

        }

        XMLPlatformUtils::Terminate();

        return 0;

}