Introduction
This tutorial shows you how to create an XML DOM document using Xerces for C++ using Visual Studio 9, and also how to output the results to a console, or save to a file. This tutorial produces the following output:
="1.0"="UTF-8"="no"
<Hello_World>
<data date="01/22/09" float="3.14159265" integer="65536">
<row index="1">Comments and data can also go in text nodes.</row>
<row description="The value of PI">3.1415926535897932384626433832795</row>
<row website="http://www.ted.com.au/">TED - ideas worth sharing.</row>
</data>
</Hello_World>
This tutorial assumes you have already downloaded the Xerces binaries, and have correctly configured your Visual Studio environment. If you need help with this, read my previous tutorial on the subject.
Include Files
For this tutorial, you will need the following include
s at a minimum:
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
This tutorial also uses the following include
s for creating sample data:
#include <time.h>
#include <string>
#include <sstream>
Namespaces
The following line (without semi-colon) will expand to use the correct Xerces namespace. The alternative is to prefix all Xerces code and functions with the XERCES_CPP_NAMESPACE::
namespace.
XERCES_CPP_NAMESPACE_USE
Initializing Xerces and the DOM
Initialize Xerces, and get the DOM implementation used for creating DOM documents:
XMLPlatformUtils::Initialize();
DOMImplementation * pDOMImplementation = NULL;
pDOMImplementation =
DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("core"));
Note: Both Xerces and Xalan follow the official specifications for the XML and XSLT languages. These can be found at the W3C.
Creating the DOM Document Using Xerces for C++
The following code block creates a DOM document and fills in some sample data. The sample data starts life as integers, floats, dates, or strings, but ultimately, everything must be converted to a wide-character string as required by Xerces.
DOMDocument * pDOMDocument = NULL;
pDOMDocument = pDOMImplementation->createDocument(L"schemas.example.com/2008/",
L"ex:Hello_World", 0);
pDOMDocument = pDOMImplementation->createDocument(0, L"Hello_World", 0);
DOMElement * pRootElement = NULL;
pRootElement = pDOMDocument->getDocumentElement();
DOMComment * pDOMComment = NULL;
pDOMComment = pDOMDocument->createComment(L"Dates are formatted mm/dd/yy."
L" Don't forget XML is case-sensitive.");
pRootElement->appendChild(pDOMComment);
DOMElement * pDataElement = NULL;
pDataElement = pDOMDocument->createElement(L"data");
wchar_t wcharBuffer[128];
_wstrdate_s(wcharBuffer, 9);
pDataElement->setAttribute(L"date", wcharBuffer);
_itow_s(65536, wcharBuffer, 128, 10);
pDataElement->setAttribute(L"integer", wcharBuffer);
std::wstringstream myStream;
myStream.precision(8);
myStream.setf(std::ios_base::fixed, std::ios_base::floatfield);
myStream << 3.1415926535897932384626433832795;
const std::wstring ws(myStream.str());
pDataElement->setAttribute(L"float", ws.c_str());
pRootElement->appendChild(pDataElement);
DOMElement * pRow = NULL;
pRow = pDOMDocument->createElement(L"row");
_itow_s(1, wcharBuffer, 128, 10);
pRow->setAttribute(L"index", wcharBuffer);
DOMText* pTextNode = NULL;
pTextNode = pDOMDocument->createTextNode(L"Comments and"
L" data can also go in text nodes.");
pRow->appendChild(pTextNode);
pDataElement->appendChild(pRow);
pRow = pDOMDocument->createElement(L"row");
pRow->setAttribute(L"description", L"The value of PI");
pTextNode = pDOMDocument->createTextNode(L"3.1415926535897932384626433832795");
pRow->appendChild(pTextNode);
pDataElement->appendChild(pRow);
pRow = pDOMDocument->createElement(L"row");
pRow->setAttribute(L"website", L"http://www.ted.com.au/");
pTextNode = pDOMDocument->createTextNode(L"TED - ideas worth sharing.");
pRow->appendChild(pTextNode);
pDataElement->appendChild(pRow);
Output the DOM Document to the Standard Output Stream
void DoOutput2Stream(DOMDocument* pmyDOMDocument)
{
DOMImplementation *pImplement = NULL;
DOMWriter *pSerializer = NULL;
XMLFormatTarget *pTarget = NULL;
pImplement = DOMImplementationRegistry::getDOMImplementation(L"LS");
pSerializer = ((DOMImplementationLS*)pImplement)->createDOMWriter();
pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
pTarget = new StdOutFormatTarget();
pSerializer->writeNode(pTarget, *pmyDOMDocument);
}
Save the DOM Document to the File System
Similar to the above section, use the following code to save a DOM document to the file system:
void DoOutput2File(DOMDocument* pmyDOMDocument, const wchar_t * FullFilePath )
{
DOMImplementation *pImplement = NULL;
DOMWriter *pSerializer = NULL;
XMLFormatTarget *pTarget = NULL;
pImplement = DOMImplementationRegistry::getDOMImplementation(L"LS");
pSerializer = ((DOMImplementationLS*)pImplement)->createDOMWriter();
pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
pTarget = new LocalFileFormatTarget(FullFilePath);
pSerializer->writeNode(pTarget, *pmyDOMDocument);
}
Clean Up
Clean up as usual.
p_DOMDocument->release();
XMLPlatformUtils::Terminate();
Known Problems with Visual Studio 2008
I've encountered the following problem compiling and linking with Xerces using Visual Studio v9 (2008). To resolve the following error...
error LNK2001: unresolved external symbol
"__declspec(dllimport) public: static wchar_t *
__cdecl xercesc_2_7::XMLString::transcode(char const * const)" (
__imp_?transcode@XMLString@xercesc_2_7@@SAPA_WQBD@Z)
...modify the following C++ language compiler option:
/Zc:wchar_t (wchar_t Is Native Type)
History
- Initial release: 2009-01-22.