Thursday, 2 May 2013

XML Writer In C++ using Xerces-DOM

The following program demonstrates how to write an XML file in C++:

* author: Aniruddha S N
* description:
* The main function uses a DOM implementation 
* to construct a DOM tree, once the dom tree is completely constructed
* it invokes the mserialiser_XML_Writer method to Serilize the DOM tree
* and write it to a xml file.
* Dependency: xerces3.1-c (code not compatible with older versions of xerces.)
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <time.h>
#include <string>
#include <sstream>
void Serialiser_XML_writer(xercesc::DOMDocument* pDOMDocument, char* FullFilePath );
using namespace std;
//below macro gives all the required namespaces for Xerces
void main()
// Pointer to our DOMImplementation.
DOMImplementation * pDOMImplementation = NULL;
// Get the DOM Implementation (used for creating DOMDocuments).
// Also see:
pDOMImplementation = 
DOMDocument * pDOMDocument = NULL;
pDOMDocument = pDOMImplementation-&gt;createDocument(L"", 
                                                  L"ex:Hello_World", 0);
DOMElement * pRootElement = NULL;
pRootElement = pDOMDocument-&gt;getDocumentElement();
// Create a Comment node, and then append this to the root element.
DOMComment * pDOMComment = NULL;
pDOMComment = pDOMDocument-&gt;createComment(L"Dates are formatted mm/dd/yy." 
              L" Don't forget XML is case-sensitive.");
// Create an Element node, then fill in some attributes,
// and then append this to the root element.
DOMElement * pDataElement = NULL;
pDataElement = pDOMDocument-&gt;createElement(L"data");
    // Copy the current system date to a buffer, then set/create the attribute.
    wchar_t wcharBuffer[128];
    _wstrdate_s(wcharBuffer, 9);
    pDataElement-&gt;setAttribute(L"date", wcharBuffer);
    // Convert an integer to a string, then set/create the attribute.
    _itow_s(65536, wcharBuffer, 128, 10);
    pDataElement-&gt;setAttribute(L"integer", wcharBuffer);
    // Convert a floating-point number to a wstring,
    // then set/create the attribute.
    std::wstringstream    myStream;
        myStream.setf(std::ios_base::fixed, std::ios_base::floatfield);
        myStream &lt;&lt; 3.1415926535897932384626433832795;
    const std::wstring ws(myStream.str());
    pDataElement-&gt;setAttribute(L"float", ws.c_str());
    // Append 'pDataElement' to 'pRootElement'.
// Create an Element node, then fill in some attributes, add some text,
// then append this to the 'pDataElement' element.
DOMElement * pRow = NULL;
pRow = pDOMDocument-&gt;createElement(L"tow");
    // Create some sample data.
    _itow_s(1, wcharBuffer, 128, 10);
    pRow-&gt;setAttribute(L"index", wcharBuffer);
    Create a text node and append this as well. Some people 
    prefer to place their data in the text node
    which is perfectly valid, others prefer to use 
    the attributes. A combination of the two is quite common.
    DOMText* pTextNode = NULL;
    pTextNode = pDOMDocument-&gt;createTextNode(L"Comments and" 
                L" data can also go in text nodes.");
// Create a new  row (this time putting data and descriptions into different places).
pRow = pDOMDocument-&gt;createElement(L"ConstantPI");
    pRow-&gt;setAttribute(L"description", L"The value of PI");
    pTextNode = pDOMDocument-&gt;createTextNode(L"3.1415");
// Create a new row.
pRow = pDOMDocument-&gt;createElement(L"UsefulLinks");
    pRow-&gt;setAttribute(L"website", L"");
    pTextNode = pDOMDocument-&gt;createTextNode(L"Blog worth Reading.");
    char* path="c:\\temp\\sample.xml";
//Release The Document after the xml file has been written

Method XML writer:

* author: Aniruddha S N
* Description: the function serializes the DOM tree 
* and writes it in XML form to the mentioned file.
#include <iostream>
#include <vector>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <time.h>
#include <string>
#include <sstream>
using namespace std;
//below macro gives all the required namespaces for Xerces
void Serialiser_XML_writer(xercesc::DOMDocument* pDOMDocument, char* FullFilePath )
DOMImplementation *pImplement = NULL;
DOMLSSerializer *pSerializer = NULL; // @DOMWriter
LocalFileFormatTarget *pTarget = NULL; 
//Return the first registered implementation that has the desired features. In this case, we are after
//a DOM implementation that has the LS feature... or Load/Save.
pImplement = DOMImplementationRegistry::getDOMImplementation(L"LS");
//From the DOMImplementation, create a DOMWriter.
//DOMWriters are used to serialize a DOM tree [back] into an XML document.
pSerializer = ((DOMImplementationLS*)pImplement)-&gt;createLSSerializer(); 
DOMLSOutput *pOutput = ((DOMImplementationLS*)pImplement)-&gt;createLSOutput();
DOMConfiguration *pConfiguration = pSerializer-&gt;getDomConfig();
// Have a nice output
if (pConfiguration-&gt;canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))
pConfiguration-&gt;setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true); 
pTarget = new LocalFileFormatTarget(FullFilePath);
//pSerializer->write(pDOMDocument->getDocumentElement(), pOutput); // missing header "" if used
pSerializer-&gt;write(pDOMDocument, pOutput); 
delete pTarget;

Output File:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ex:Hello_World xmlns:ex="">

  <!--Dates are formatted mm/dd/yy. Don't forget XML is case-sensitive.-->

  <data date="05/02/13" float="3.14159265" integer="65536">
    <tow index="1">Comments and data can also go in text nodes.</tow>
    <ConstantPI description="The value of PI">3.1415</ConstantPI>
    <UsefulLinks website="">Blog worth Reading.</UsefulLinks>


1 comment:

  1. Sorry for the poor line format, you may have to arrange the code lines, rest all things are perfectly right.