Hi Jesse,

Basically what I want to achieve is to recursively parse the XML buffer & 
create required Class Object at each recursive call of the class object. 

Eg: I have 3 Classes defined as C1, C2 & C3. Each class has a virtual member 
function by the name "XMLToObject(XMLBuffer)" which when invoked will fill the 
member variables of  respective class.

Please find the code in the attached file "XML code.txt". This code works 
perfectly fine on the sample XML shown at the end of the same file. 

Now referring to second attachment, "XML file.txt" consists of the XML I want 
to parse. As you can see there are various elements. Each Element represent a 
corresponding class similar to the CNode class present in "XML code.txt". That 
is, there is a Class as CRequest, CCommand, CData, etc. (All are independent 
classes, not derived from any one) And each of this class hasa member function 
XMLToObject(XMLBuffer) which takes in the desired XML buff & creates its 
required objects. 

CRequest has its member variables as CCommand *cmd, CData *data.
CCommand has its member variables as char * CmdID, char *ObjName, etc. and so 
on.

Now in my code, I am passing the whole buffer, i.e. generating the DomDocument 
object out of the XML file. How can I fetch the required XML content from the 
complete XML & pass it on further.

I need a way where if I call the XMLToObject of say CRequest object, it should 
recursively call other XMLToObject too, because CRequest has CCommand as its 
member who also need to initialize its member variables using the XML data. 

I am new to XML parsing, & have not used SAX at all. Will like to stick to DOM, 
as most of the things are written using DOM. 

I hope, I have tried to put the problem in the correct words. 

Thanks in advance.

~Amit




From: Jesse Pelton <j...@pkc.com>
To: c-users@xerces.apache.org
Sent: Thursday, January 22, 2009 7:01:20 PM
Subject: RE: Parsing XML using DOM in VC++

First, you need to provide some specifics as to what you're doing and
what's not working as expected.  A small, well-organized code sample is
one way to provide that.

Second, SAX may be a better (more natural and more efficient) solution
to your problem than DOM.  If you're just traversing the DOM in order to
build your own in-memory representation, you could avoid the CPU and
memory overhead of building a DOM by creating your objects in response
to SAX events.

And finally, you might want to look at CodeSynthesis XSD, "an
open-source, cross-platform W3C XML Schema to C++ data binding compiler"
based on Xerces (http://www.codesynthesis.com/products/xsd/) and similar
products.

-----Original Message-----
From: Amit [mailto:amitpard...@yahoo.com] 
Sent: Thursday, January 22, 2009 6:28 AM
To: c-users@xerces.apache.org
Cc: Amitsingh Pardesi
Subject: Parsing XML using DOM in VC++

Hi,

I am using Visual Studio 2008 to develop a Windows Console Application. 

I need to parse the XML Buffer and create Class objects from each
Element node and again re-create the XML from these objects. I am using
Xerces 2.8 on Windows platform. I am able to do the same for a simple
XML file like the one below: 

<?xml version="1.0" encoding="utf-8" ?>
<RootInfo>
  <Node>
    <NodeID>81023492-ACA3-98Af-BF38-7242AQ87088X</NodeID>
    <NodeIP>192.168.0.222</NodeIP>
    <NodeUserName>abcd</NodeUserName>
    <NodePassword>aabbccdd</NodePassword>
    <NodeType>Source</NodeType>
  </Node>
  <Node>
    <NodeID>4S123492-ACG0-98Af-BF38-K900F787IJ5M</NodeID>
    <NodeIP>192.170.7.21</NodeIP>
    <NodeUserName>Amit</NodeUserName>
    <NodePassword>amitpass</NodePassword>
    <NodeType>GUI</NodeType>
  </Node>
</RootInfo>

But when it comes to a more complex XML file like the one mentioned
below, 

<?xml version="1.0" standalone="yes"?>
<RootInfo>
    <Request>
        <Command>
            <CommandID>5f27-4e40-b6da-b1cb</CommandID>
            <ObjectName>File</ObjectName>
            <OperationName>Add</OperationName>
            <CommandType>Sync</CommandType>
        </Command>
        <Data>
           <DataElem1>
             <Text1>ABC</Text1>
             <Text2>ASDH</Text2>
           </DataElem1>
           <DataElem2>
             <File1>asdas.bat</File1>
             <file2>askjd.doc</file2>
           </DataElem2>
           <Status>
             <state>append</state>
             <state>add</state>
           </Status>
         </Data>
         <Error>
            <ErrorID/>
            <ErrorMessage/>
          </Error>
     </Request>
    <Response>
    <Command>
      <CommandID>5f27-4e40-b6da-b1cb</CommandID>
    </Command>
    <Data>
      <DataElem2>
        <File1>asdas.bat</File1>
        <file2>askjd.doc</file2>
      </DataElem2>
      <Status>
        <state>appended</state>
        <state>added</state>
      </Status>
    </Data>
      <Error>
      <ErrorID>62342-s838s-34jf3-eir8e</ErrorID>
      <ErrorMessage>Command Success</ErrorMessage>
      </Error>
    </Response>
</RootInfo>

I am not able to parse it correctly using DOM. Each node has a
corresponding Class to store the details. The class of RootInfo will
have two members, by the name Request & Response beloging to Class
ReqRes. They both will in turn have 3 members by the name Command, Data
& Error of respective class and so on. 

How do I do this? Any pointer to resolve this will be appreciated. 

Regards,
Amit


      
class CNode 
{
public:
        TCHAR *m_NodeID;
        TCHAR *m_NodeIP;
        TCHAR *m_NodeUserName;
        TCHAR *m_NodePassword;
        TCHAR *m_NodeType;

        int ObjectToXML_Node();
        int XMLToObject_Node();

        CNode(void);
        CNode(const CNode *);
        virtual ~CNode(void);
};


int CNode::XMLToObject_Node ()
{
    try
    {
        XercesDOMParser* parser = new XercesDOMParser();
        parser->setValidationScheme(XercesDOMParser::Val_Always);
        parser->setDoNamespaces(true);

        char* xmlFile = "C:\\NodeInfo.xml";
        parser->parse(xmlFile);

        xercesc_2_8::DOMDocument *pDomDoc = parser->getDocument ();
        if  ( pDomDoc != NULL )
        {
            DOMElement* pDomElement = pDomDoc->getDocumentElement ();
       
            //XMLCh *StrID = XMLString::transcode("Node");
            DOMNodeList* pNodeList = pDomElement->getElementsByTagName 
(X("Node"));
           
            if ( pNodeList != NULL )
            {
                XMLSize_t len =  pNodeList->getLength ();
                for ( int i = 0 ; i < (int) len ; i++)
                {
                    DOMElement* n = (DOMElement*) pNodeList->item (i);

                    // Get Node ID
                    this->m_NodeID = (TCHAR *) n->getElementsByTagName 
(X("NodeID"))->item (0)->getFirstChild()->getNodeValue ();
                   
                    // Get Node IP
                    this->m_NodeIP = (TCHAR *) n->getElementsByTagName 
(X("NodeIP"))->item (0)->getFirstChild()->getNodeValue ();
                   
                    // Get Node Username
                    this->m_NodeUserName = (TCHAR *)n->getElementsByTagName 
(X("NodeUsername"))->item (0)->getFirstChild()->getNodeValue ();
                   
                    // Get Node Password
                    this->m_NodePassword = (TCHAR *)n->getElementsByTagName 
(X("NodePassword"))->item (0)->getFirstChild()->getNodeValue ();
                   
                    // Get Node Type
                    this->m_NodeType = (TCHAR *)n->getElementsByTagName 
(X("NodeType"))->item (0)->getFirstChild()->getNodeValue ();

                    printf("\nNodeID: %S\nNode IP: %S\nNode Type: %S\nUserName: 
%S\nPassword: %S\n",
                        this->m_NodeID, this->m_NodeIP, this->m_NodeType, 
this->m_NodeUserName, this->m_NodePassword);
                }
            }
            pDomElement->release ();
        }
        pDomDoc->release ();
        delete parser;
    }
    catch (const DOMException& toCatch)
    {
        char* message = XMLString::transcode(toCatch.msg);
        XMLString::release(&message);
        return 1;
    }   
    catch (const XMLException& toCatch)
    {
        char* message = XMLString::transcode(toCatch.getMessage());     
        XMLString::release(&message);
        return 1;
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
        XMLPlatformUtils::Initialize(); 

        CNode *node = new CNode();
        node->XMLToObject_Node ();
        node->~CNode();
        delete node;

        XMLPlatformUtils::Terminate();
        return 0;
}


// Sample XML 
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Root>
  <Node>
    <NodeID>4S12-ACG0-98Af-BF38-K900</NodeID>
    <NodeIP>192.170.7.21</NodeIP>
    <NodeUserName>Amitsingh</NodeUserName>
    <NodePassword>pardesi</NodePassword>
    <NodeType>Client-GUI</NodeType>
  </Node>
</Root>




<?xml version="1.0" encoding="utf-8" ?>
<RootInfo>
  <Request>
    <Command>
      <CommandID>9870</CommandID>
      <ObjectName>Node</ObjectName>
      <OperationName>Add</OperationName>
    </Command>
    <Data>
      <Node>
        <NodeID>50417992-A723-4c6f-BF38-7242B6C123A9</NodeID>
        <NodeName>muktadev</NodeName>
        <NodeIP>192.168.0.220</NodeIP>
        <NodeUserName>Mukta</NodeUserName>
        <NodePassword>Vaidya</NodePassword>
        <NodeType>Target</NodeType>
      </Node>
      <Node>
        <NodeID>81023492-ACA3-98Af-BF38-7242AQ87088X</NodeID>
        <NodeName>amitdev</NodeName>
        <NodeIP>192.168.0.222</NodeIP>
        <NodeUserName>Amit</NodeUserName>
        <NodePassword>Pardesi</NodePassword>
        <NodeType>Source</NodeType>
      </Node>
    </Data>
    <Error/>
  </Request>
  <Response>
    <Command/>
    <Data/>
    <Error/>
  </Response>
</RootInfo>

Reply via email to