Discussion:
IBM Xerces Guide
(too old to reply)
m***@lycos.com
2008-01-07 05:21:07 UTC
Permalink
My apologies if this is off topic.

Sometime back I had bookmarked the IBM Xerces Guide page (http://
www.ibm.com/developerworks/xml/library/x-xercc2/). I am not able to
navigate to the page today. Does anyone know if this page is down
temporarily or if the link has been moved?

Thanks,
Masood
m***@lycos.com
2008-01-07 15:16:33 UTC
Permalink
Post by m***@lycos.com
My apologies if this is off topic.
Sometime back I had bookmarked the IBM Xerces Guide page (http://www.ibm.com/developerworks/xml/library/x-xercc2/). I am not able to
navigate to the page today. Does anyone know if this page is down
temporarily or if the link has been moved?
Thanks,
Masood
Thank Goodness! The link is up. For a moment I was s**t scared. I
was wondering if we had lost the link, with all the excellent coding
snippets from Rick Parrish (Make the most of Xerces-C++ Part1/Part2)
for good. Anyway, here are the coding gems from Parrish.

/***************************************************
** Listing 5. SAX parser boilerplate (sans handlers)
***************************************************/
// GraphMain.cpp
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/ContentHandler.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <stdio.h>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

#include "GraphHandler.h"
#include "XercesString.h"

#ifdef XERCES_CPP_NAMESPACE_USE
XERCES_CPP_NAMESPACE_USE
#endif

int main(int argc, char* argv[])
{
if (argc < 2) return -1;

// initialize the XML library
XMLPlatformUtils::Initialize();
if ( !access(argv[1], 04) )
{
printf("Cheesey Bar Graph!\n");

XercesString wstrPath(argv[1]);

SAX2XMLReader* pParser = XMLReaderFactory::createXMLReader();
LocalFileInputSource source(wstrPath);

// our application specific handler.
GraphHandler handler;

pParser->setFeature( XercesString("http://xml.org/sax/features/
validation"), true );
pParser->setFeature( XercesString("http://apache.org/xml/features/
validation/dynamic"), true );
pParser->setContentHandler(&handler);
pParser->setErrorHandler(&handler);
pParser->parse(source);
}
// terminate the XML library
XMLPlatformUtils::Terminate();
getchar();
return 0;
}


/***************************************************
** Listing 6. Example SAX event-handler declaration
***************************************************/

//GraphHandler.hpp
#include <xercesc/sax2/DefaultHandler.hpp>
#include <vector>
#include <algorithm>

#include "XercesString.h"

struct department
{
XercesString mName;
double mSales;
double mInventory;
double mLabor;

department() : mSales(0.0), mInventory(0.0), mLabor(0.0) { };

department(const department &copy) : mName(copy.mName)
{
mSales = copy.mSales;
mLabor = copy.mLabor;
mInventory = copy.mInventory;
};

department(const XMLCh *wstr) : mName(wstr), mSales(0.0),
mInventory(0.0), mLabor(0.0) { };

virtual ~department() { };
};

class GraphHandler : public DefaultHandler
{
XercesString mName;
std::vector<department> mList;

public:
virtual void startDocument();

virtual void endDocument();

virtual void startElement(
const XMLCh* const uri,
const XMLCh* const localname,
const XMLCh* const qname,
const Attributes& attrs);

virtual void endElement(
const XMLCh* const uri,
const XMLCh* const localname,
const XMLCh* const qname);

virtual void characters(
const XMLCh* const chars,
const unsigned int length);
};


/***************************************************
** Listing 7. Example SAX event-handler declaration
***************************************************/
// GraphHandler.cpp
#include "GraphHandler.h"
#include <xercesc/sax2/Attributes.hpp>
#include <stdio.h>
#include "XercesString.h"
#include <float.h>

static const bool bDebug = false;

void GraphHandler::startDocument()
{
if (bDebug) printf("starting...\n");
}

// given a value, minimum, maximum and overall discrete number of
tiles;
// computes how many tiles or blocks will be displaced by the value.
static int tiles(double fValue, double fMin, double fMax, int nSpan)
{
double fDel = fMax - fMin;
fValue -= fMin;
if (fDel <= FLT_MIN) fValue = 0.;
else fValue /= (fMax - fMin);
return (int)(fValue * nSpan);
}

// returns a null terminated string whose length
// is the requested span (up to some limit).
static const char *bars(int nSpan)
{
static const char strBars[] =
"########################################"
"########################################";
const int kLimit = sizeof strBars - 1;
if (nSpan > kLimit) nSpan = kLimit;
return &strBars[kLimit - nSpan];
}

void GraphHandler::endDocument()
{
int nDex = 0;
double fMin = 0.0, fMax = 0.0;
if (bDebug) printf("...ends.\n");

const unsigned kLimit = mList.size();
if (bDebug)
{
printf("Department Sales Inventory Labor\n");
printf("-------------------- --------- --------- ---------\n");
}
for (nDex = 0; nDex < kLimit; nDex++)
{
double fValue = mList[nDex].mSales;
if (!nDex)
fMin = fMax = fValue;
else
{
if (fValue > fMax) fMax = fValue;
else if (fValue < fMin) fMin = fValue;
}
if (bDebug)
{
char *strName = XMLString::transcode(mList[nDex].mName);
printf("%-20.20s %9.2f %9.2f %9.2f\n", strName,
mList[nDex].mSales,
mList[nDex].mInventory, mList[nDex].mLabor);
XMLString::release(&strName);
}
}
const int nSpan = 70;
fMin *= 0.8;
for (nDex = 0; nDex < kLimit; nDex++)
{
int nWidth = tiles(mList[nDex].mSales, fMin, fMax, nSpan);
char *strName = XMLString::transcode(mList[nDex].mName);
printf("%-20.20s (%7.0f) %s\n", strName, mList[nDex].mSales,
bars(nWidth) );
XMLString::release(&strName);
}
}

void GraphHandler::startElement(
const XMLCh* const uri,
const XMLCh* const localname,
const XMLCh* const qname,
const Attributes& attrs)
{
if (bDebug) printf("element...[%ws, %ws, %ws]\n", uri, localname,
qname);

const XercesString kstrFigures("figures");
const XercesString kstrType("type");
const XercesString kstrValue("value");
const XercesString kstrDepartment("department");
const XercesString kstrSales("sales");
const XercesString kstrLabel("label");
const XercesString kstrLabor("labor");
const XercesString kstrInventory("inventory");
const XercesString kstrName("name");
const XercesString kstrCorporate("corporate");

if ( !XMLString::compareString(localname, kstrFigures) )
{
const XercesString wstrType( attrs.getValue(kstrType) );
const XercesString wstrValue( attrs.getValue(kstrValue) );
double fValue = wcstod(wstrValue, NULL);

if (mList.size())
{
if ( !XMLString::compareString(wstrType, kstrSales) )
mList[mList.size() - 1].mSales = fValue;
else if ( !XMLString::compareString(wstrType, kstrInventory) )
mList[mList.size() - 1].mInventory = fValue;
else if ( !XMLString::compareString(wstrType, kstrLabor) )
mList[mList.size() - 1].mLabor = fValue;
}
}
else if ( !XMLString::compareString(localname, kstrDepartment) )
{
const XercesString wstrValue( attrs.getValue(kstrName) );
mList.insert(mList.end(), department(wstrValue) );
}
else if ( !XMLString::compareString(localname, kstrCorporate) )
{
mName = XMLString::replicate( attrs.getValue(kstrName) );
}
}

void GraphHandler::endElement(
const XMLCh* const uri,
const XMLCh* const localname,
const XMLCh* const qname)
{
if (bDebug) printf("...end element.\n");
}

void GraphHandler::characters(
const XMLCh* const chars,
const unsigned int length)
{
if (!bDebug) return;
char *strChars = new char [length+1];
XMLString::transcode(chars, strChars, length);
strChars[length] = 0;
printf("chars [ %-0.*s ] \n", length, strChars);
delete[] strChars;
}


/***************************************************
** Listing 8. DOM loading and exception boilerplate
***************************************************/
#include <xercesc/dom/DOM.hpp>
#include "XercesString.h"

// boilerplate DOM loading example.
int main(int argc, char *argv[])
{
bool bFailed = false;
if (argc < 2)
return -1;

// initialize the XML library.
XMLPlatformUtils::Initialize();
// create new parser instance.
XercesDOMParser *parser = new XercesDOMParser;
if (parser)
{
parser->setValidationScheme(XercesDOMParser::Val_Auto);
parser->setDoNamespaces(false);
parser->setDoSchema(false);

// skip this if you haven't written your own error reporter class.
DOMTreeErrorReporter *errReporter = new DOMTreeErrorReporter;
parser->setErrorHandler(errReporter);

parser->setCreateEntityReferenceNodes(false);
//parser->setToCreateXMLDeclTypeNode(true);
try
{
XercesString src(argv[1]);
LocalFileInputSource source(src);
parser->parse(source);
bFailed = parser->getErrorCount() != 0;
if (bFailed)
{
std::cerr << "Parsing " << argv[1];
std::cerr << " error count: " << parser->getErrorCount() <<
std::endl;
}
}
catch (const DOMException& e)
{
std::cerr << "DOM Exception parsing ";
std::cerr << strSrc;
std::cerr << " reports: ";
// was message provided?
if (e.msg)
{
// yes: display it as ascii.
char *strMsg = XMLString::transcode(e.msg);
std::cerr << strMsg << std::endl;
XMLString::release(&strMsg);
}
else
// no: just display the error code.
std::cerr << e.code << std::endl;

bFailed = true;
}
catch (const XMLException& e)
{
std::cerr << "XML Exception parsing ";
std::cerr << argv[1];
std::cerr << " reports: ";
std::cerr << e.getMessage() << std::endl;
bFailed = true;
}
catch (const SAXException& e)
{
std::cerr << "SAX Exception parsing ";
std::cerr << argv[1];
std::cerr << " reports: ";
std::cerr << e.getMessage() << std::endl;
bFailed = true;
}
catch (...)
{
std::cerr << "An exception parsing ";
std::cerr << argv[1] << std::endl;
bFailed = true;
}
// did the input document parse okay?
if (!bFailed)
{
DOMNode *pDoc = parser->getDocument();
// insert code to do something with the DOM document here.
}
}
XMLPlatformUtils::Terminate();
getchar();
return 0;
}


/***************************************************
** Listing 9. DOM synthesis example
***************************************************/
// DOM2.cpp
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <iostream>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/dom/impl/DOMWriterImpl.hpp>

#include "XercesString.h"

#ifdef XERCES_CPP_NAMESPACE_USE
XERCES_CPP_NAMESPACE_USE
#endif

// objectives:
// 1. synthesize an XML document
// 2. traverse/explore an XML document
// 3. modify an XML document

int main(int argc, char *argv[])
{
DOMDocumentType* pDoctype = NULL;
DOMDocument* pDoc = NULL;
DOMNode *pNode = NULL;
DOMImplementation *pImplement = NULL;
// these two are needed to display DOM output.
DOMWriter *pSerializer = NULL;
XMLFormatTarget *pTarget = NULL;

// initialize the XML library
XMLPlatformUtils::Initialize();

// get a serializer, an instance of DOMWriter (the "LS" stands for
load-save).
pImplement =
DOMImplementationRegistry::getDOMImplementation(XercesString("LS"));
pSerializer = ( (DOMImplementationLS*)pImplement )-
Post by m***@lycos.com
createDOMWriter();
pTarget = new StdOutFormatTarget();
// set user specified end of line sequence and output encoding
pSerializer->setNewLine( XercesString("\n") );

// set feature if the serializer supports the feature/mode
if ( pSerializer->canSetFeature(XMLUni::fgDOMWRTSplitCdataSections,
false) )
pSerializer->setFeature(XMLUni::fgDOMWRTSplitCdataSections, false);

if ( pSerializer-
Post by m***@lycos.com
canSetFeature(XMLUni::fgDOMWRTDiscardDefaultContent, false) )
pSerializer->setFeature(XMLUni::fgDOMWRTDiscardDefaultContent,
false);

if ( pSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint,
false) )
pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);

if ( pSerializer->canSetFeature(XMLUni::fgDOMWRTBOM, false) )
pSerializer->setFeature(XMLUni::fgDOMWRTBOM, false);

// create a document
pDoctype = pImplement->createDocumentType( XercesString("XHTML"),
NULL, NULL );
pDoc = pImplement->createDocument( XercesString("XHTML"),
XercesString("XHTML"),
pDoctype );
if (pDoc)
{
// output related nodes are prefixed with "svg"
// to distinguish them from input nodes.
pDoc->setEncoding( XercesString("UTF-8") );
pDoc->setStandalone(true);
pDoc->setVersion( XercesString("1.0") );
DOMElement *pRoot = pDoc->getDocumentElement();

// Create a root element
//DOMElement root = pDoc->createElement("XHTML") );
//pDoc->appendChild(root);
//Creating the siblings of root
DOMElement* pHead = pDoc->createElement( XercesString("HEAD") );
pRoot->appendChild(pHead);
DOMElement* pBody = pDoc->createElement( XercesString("BODY") );
pRoot->appendChild(pBody);
DOMElement* pTitle = pDoc->createElement( XercesString("TITLE") );
pHead->appendChild(pTitle);
DOMText* pHeading = pDoc->createTextNode( XercesString("Document
Title") );
pTitle->appendChild(pHeading);
//Attaching texts to few siblings
DOMElement* pParagraph = pDoc->createElement( XercesString("p") );
pBody->appendChild(pParagraph);
DOMText* pFragment = pDoc->createTextNode(
XercesString("The quick & brown fox jumped over the lazy
dog") );
pParagraph->appendChild(pFragment);
DOMText* pTextnode =
pDoc->createTextNode( XercesString("some <random> text goes
here") );
pBody->appendChild(pTextnode);

DOMElement* pTable = pDoc->createElement( XercesString("table") );
pBody->appendChild(pTable);

DOMAttr* pAnnotate = pDoc-
Post by m***@lycos.com
createAttribute( XercesString("width") );
pAnnotate->setValue( XercesString("100%") );
pTable->setAttributeNode(pAnnotate);

DOMElement* pRow = pDoc->createElement( XercesString("tr") );
pTable->appendChild(pRow);
DOMElement* pData = pDoc->createElement( XercesString("td") );
pRow->appendChild(pData);
DOMText* pContent = pDoc-
Post by m***@lycos.com
createTextNode( XercesString("Highlights") );
pData->appendChild(pContent);

fflush(stdout);
pSerializer->writeNode(pTarget, *pDoc);

// create a walker to visit all text nodes.
DOMNode* pCurrent = NULL;
DOMTreeWalker* walker = pDoc->createTreeWalker(pRoot,
DOMNodeFilter::SHOW_TEXT, NULL, true);
// use the tree walker to print out the text nodes.
std::cout<< "walker:\n";
for ( pCurrent = walker->nextNode();
pCurrent != 0; pCurrent = walker->nextNode() )
{
char *strValue = XMLString::transcode( pCurrent->getNodeValue() );
std::cout << strValue;
XMLString::release(&strValue);
}
std::cout<< '\n';

// create an iterator to visit all text nodes.
DOMNodeIterator* iterator = pDoc->createNodeIterator(pRoot,
DOMNodeFilter::SHOW_TEXT, NULL, true);
// use the tree walker to print out the text nodes.
std::cout<< "iterator:\n";
for ( pCurrent = iterator->nextNode();
pCurrent != 0; pCurrent = iterator->nextNode() )
{
char *strValue = XMLString::transcode( pCurrent->getNodeValue() );
std::cout << strValue;
XMLString::release(&strValue);
}
std::cout<< '\n';

// use the cloneNode to add a duplicate row to the table.
DOMNode* pClone = pRow->cloneNode(true);
pTable->appendChild(pClone);
// add another cloned row to the table.
pClone = pRow->cloneNode(true);
pTable->appendChild(pClone);
// dump out the modified result.
pSerializer->writeNode(pTarget, *pDoc);

// make another clone of the first row but this time we'll
// use an iterator to locate the row's text node, replace
// the text, and then swap out the entire row in the table.
pClone = pRow->cloneNode(true);
DOMNodeIterator* pZap = pDoc->createNodeIterator(pClone,
DOMNodeFilter::SHOW_TEXT, NULL, true);
// I can get away with the typecast here since I know
// the SHOW_TEXT filtering will only return text nodes.
DOMText* pChange = static_cast<DOMText*>( pZap->nextNode() );
pChange->setData( XercesString("replacement row") );
pTable->replaceChild(pClone, pRow);
// dump out the modified result.
pSerializer->writeNode(pTarget, *pDoc);

// blow away the first row altogether and remove
// the width attribute from the table.
pTable->removeAttribute( XercesString("width") );
pTable->removeChild(pClone);
// dump out the modified result.
pSerializer->writeNode(pTarget, *pDoc);
std::cout<< "\n";

//delete walker;
//delete iterator;

}
getchar();

delete pTarget;
delete pSerializer;
delete pDoc;
delete pDoctype;

// terminate the XML library
XMLPlatformUtils::Terminate();
return 0;
}


/***************************************************
** Listing 10. Creating a formatter for serialization
***************************************************/
#include "XercesString.h"

void save_to_file(DOMDocument *pDoc, const char *strPath)
{
XercesString wstrPath( XMLString::transcode(strPath) );
if (wstrPath)
{
DOMWriterImpl writer;
LocalFileFormatTarget fileTarget(wstrPath);

// write the resulting document.
writer.setEncoding( XercesString("UTF-8") );
writer.writeNode(&fileTarget, *pDoc);
}
}

void dump_xml(DOMDocument *pDoc)
{
DOMImplementation *pImplement = NULL;
// these two are needed to display DOM output.
DOMWriter *pSerializer = NULL;
XMLFormatTarget *pTarget = NULL;

// get a serializer, an instance of DOMWriter (the "LS" stands for
load-save).
pImplement =
DOMImplementationRegistry::getDOMImplementation(XercesString("LS"));
pSerializer = ( (DOMImplementationLS*)pImplement )-
Post by m***@lycos.com
createDOMWriter();
pTarget = new StdOutFormatTarget();
// set user specified end of line sequence and output encoding
pSerializer->setNewLine( XercesString("\n") );

// set feature if the serializer supports the feature/mode
if ( pSerializer->canSetFeature(XMLUni::fgDOMWRTSplitCdataSections,
false) )
pSerializer->setFeature(XMLUni::fgDOMWRTSplitCdataSections, false);

if ( pSerializer-
Post by m***@lycos.com
canSetFeature(XMLUni::fgDOMWRTDiscardDefaultContent, false) )
pSerializer->setFeature(XMLUni::fgDOMWRTDiscardDefaultContent,
false);

// turn off serializer "pretty print" option
if ( pSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint,
false) )
pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);

if ( pSerializer->canSetFeature(XMLUni::fgDOMWRTBOM, false) )
pSerializer->setFeature(XMLUni::fgDOMWRTBOM, false);

pSerializer->writeNode(pTarget, *pDoc);

}


/***************************************************
** Listing 11. Pretty-printing XML
***************************************************/
// turn on serializer "pretty print" option

if ( pSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint,
true) )
pSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);


/***************************************************
** Listing 12. Creating an iterator to visit all text nodes
***************************************************/
// create an iterator to visit all text nodes.
DOMNodeIterator iterator =
doc.createNodeIterator(root, DOMNodeFilter::SHOW_TEXT, NULL, true);
// use the tree walker to print out the text nodes.
for ( current = iterator.nextNode(); current != 0; current =
iterator.nextNode() )
// note: this leaks memory!
std::cout << current.getNodeValue().transcode();
std::cout << std::endl;


/***************************************************
** Listing 13. Creating a walker to visit all text nodes
***************************************************/
// create a walker to visit all text nodes.
DOMTreeWalker walker =
doc.createTreeWalker(root, DOMNodeFilter::SHOW_TEXT, NULL, true);
// use the tree walker to print out the text nodes.
for (DOMNode current = walker.nextNode(); current != 0; current =
walker.nextNode() )
// note: this leaks memory!
std::cout << current.getNodeValue().transcode();
std::cout << std::endl;


/***************************************************
** Listing 17. Creating a walker to visit all text nodes
***************************************************/
Listing 17. Code to produce SVG from source XML

// svg.cpp
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/impl/DOMWriterImpl.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <iostream>
#include <xercesc/sax/SAXException.hpp>
#include <xercesc/dom/DOMWriter.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <stdio.h>
#include <stdlib.h>
#include "XercesString.h"

static XMLCh *value(XMLCh wszBuf[], unsigned uVal)
{
char szLocal[32] = {0};
sprintf(szLocal, "%u", uVal);
XMLString::transcode(szLocal, wszBuf, 32);
return wszBuf;
}

static bool getvalue(DOMElement &department, const XMLCh *strAttr,
long *pnValue)
{
bool bFound = false;
DOMNode *pCursor = department.getFirstChild();

while (pCursor != NULL && !bFound)
{
// is this a <department> element?
if ( pCursor->getNodeType() == DOMNode::ELEMENT_NODE &&
!XMLString::compareString(pCursor->getNodeName(),
XercesString("figures") ) )
{
DOMElement *pFigure = (DOMElement*)pCursor;
const XMLCh *strType = pFigure-
Post by m***@lycos.com
getAttribute( XercesString("type") );
bFound = !XMLString::compareString(strType, strAttr);
if (bFound)
{
const XMLCh *strValue = pFigure-
Post by m***@lycos.com
getAttribute( XercesString("value") );
char *strTmp = XMLString::transcode(strValue);
*pnValue = strtol(strTmp, NULL, 0);
}
}
pCursor = pCursor->getNextSibling();
}
return bFound;
}

static bool getrange(DOMDocument &doc, const XMLCh *strAttr, long
*pnMin, long *pnMax)
{
long nMin = 0L, nMax = 0L;
bool bOnce = false;
DOMElement* pCorporate = doc.getDocumentElement();
DOMNode* pCursor = pCorporate->getFirstChild();
while (pCursor != NULL)
{
// is this a <department> element?
if ( pCursor->getNodeType() == DOMNode::ELEMENT_NODE &&
!XMLString::compareString(pCursor->getNodeName(),
XercesString("department") ) )
{
long nValue = 0L;
DOMElement* pDepartment = (DOMElement *)pCursor;
if ( getvalue(*pDepartment, strAttr, &nValue) )
{
if (bOnce)
{
if (nMin > nValue) nMin = nValue;
if (nMax < nValue) nMax = nValue;
}
else nMin = nMax = nValue;
bOnce = true;
}
}
pCursor = pCursor->getNextSibling();
}
*pnMax = nMax;
*pnMin = nMin;
return bOnce;
}

// transforms input corporate XML data to SVG viewable XML output
data.
static bool dom2svg(DOMDocument &doc, const XMLCh *strAttr,
DOMDocument **ppSVG)
{
static const char *strColors[] =
{"red", "blue", "yellow", "violet", "orange", "green"};
const unsigned kLimit = sizeof strColors / sizeof strColors[0];
unsigned uColor = 0; // use as a color index
long nMin = 0L, nMax = 0L, nRange = 0L;
DOMDocument *pSVG = NULL;

if ( !getrange(doc, strAttr, &nMin, &nMax) )
return false;

nRange = nMax - nMin;
// these next three lines of code create our output object,
// set it's doctype, and create the root document element.
DOMImplementation *pImpl = DOMImplementation::getImplementation();
DOMDocumentType* pDoctype = pImpl-
Post by m***@lycos.com
createDocumentType( XercesString("svg"), NULL,
XercesString("svg-20000303-stylable.dtd") );
pSVG = pImpl->createDocument(XercesString("svg"),
XercesString("svg"), pDoctype);
if (pSVG != NULL)
{
// output related nodes are prefixed with "svg"
// to distinguish them from input nodes.
pSVG->setEncoding( XercesString("UTF-8") );
DOMElement *pSvgRoot = pSVG->getDocumentElement();
// sneak in the XML declaration just ahead of the doctype.
//pSVG->insertBefore(svgDecl, pSVG->getDoctype() );
// locate the XML root <corporate> element
DOMElement* pCorporate = doc.getDocumentElement();
// did we locate the root element?
if (pCorporate != NULL)
{
XMLCh wszBuf[32] = {0};
unsigned uX = 20, uY = 20;
// yes: walk through the list of department elements beneath it.
DOMNode* pCursor = pCorporate->getFirstChild();
while (pCursor != NULL)
{
// is this a <department> element?
if ( pCursor->getNodeType() == DOMNode::ELEMENT_NODE &&
!XMLString::compareString(pCursor->getNodeName(),
XercesString("department") ) )
{
XercesString wstrStyle("stroke:node; fill:");
DOMElement* pDepartment = (DOMElement *)pCursor;
long nValue = 0L;
if ( getvalue(*pDepartment, strAttr, &nValue) )
{
// yes: create an SVG branch for this department
DOMElement* pSvgG = pSVG-
Post by m***@lycos.com
createElement( XercesString("g") );
pSvgRoot->setAttribute( XercesString("width"),
value(wszBuf, 320) );
pSvgRoot->setAttribute( XercesString("height"),
value(wszBuf, 200) );
pSvgRoot->appendChild(pSvgG);
// this <g> element will hold any SVG attributes (like
font size
// and color) to be shared among the elements for this
department.
DOMElement* pSvgRect = pSVG-
Post by m***@lycos.com
createElement( XercesString("rect") );
pSvgG->appendChild(pSvgRect);
pSvgG->setAttribute( XercesString("style"),
XercesString("font-size:14") );
// fill in the <rect> attributes
wstrStyle.append( XercesString(strColors[uColor++ %
kLimit]) );
pSvgRect->setAttribute( XercesString("style"),
wstrStyle );
pSvgRect->setAttribute( XercesString("x"), value(wszBuf, uX
+80) );
pSvgRect->setAttribute( XercesString("y"), value(wszBuf,
uY) );
if (!nRange) nValue = 0;
else nValue = 80 * (nValue - nMin) / nRange;
nValue += 20;
pSvgRect->setAttribute( XercesString("width"),
value(wszBuf, nValue) );
pSvgRect->setAttribute( XercesString("height"),
value(wszBuf, 20) );
DOMElement* pSvgText = pSVG-
Post by m***@lycos.com
createElement( XercesString("text") );
pSvgG->appendChild(pSvgText);
DOMText* pSvgName = pSVG->createTextNode( pDepartment-
Post by m***@lycos.com
getAttribute( XercesString("name") ) );
pSvgText->setAttribute( XercesString("x"), value(wszBuf,
uX) );
pSvgText->setAttribute( XercesString("y"), value(wszBuf, uY
+15) );
pSvgText->appendChild(pSvgName);
uY += 20;
}
}
pCursor = pCursor->getNextSibling();
}
DOMElement* pSvgText = pSVG-
Post by m***@lycos.com
createElement( XercesString("text") );
pSvgText->setAttribute( XercesString("x"), value(wszBuf, uX) );
pSvgText->setAttribute( XercesString("y"), value(wszBuf, uY
+15) );
DOMText* pSvgDisclaimer = pSVG-
Post by m***@lycos.com
createTextNode( XercesString("Reported figures are preliminary
only.") );
pSvgText->appendChild(pSvgDisclaimer);
pSvgText->setAttribute( XercesString("style"),
XercesString("font-size:10") );
pSvgRoot->appendChild(pSvgText);
}
}
*ppSVG = pSVG;
return true;
}

// Tries to return an XML DOM document
// object for a given file name.
static bool doc2dom(const XMLCh *src, DOMDocument** ppDoc)
{
bool bSuccess = false;
//DOMString strMessage;

XercesDOMParser *parser = new XercesDOMParser;
if (parser)
{
char *strSrc = XMLString::transcode(src);
parser->setValidationScheme(XercesDOMParser::Val_Auto);
parser->setDoNamespaces(false);
parser->setDoSchema(false);
parser->setCreateEntityReferenceNodes(false);
//parser->setToCreateXMLDeclTypeNode(true);
try
{
LocalFileInputSource source(src);
bSuccess = false;
parser->parse(source);
bSuccess = parser->getErrorCount() == 0;
if (!bSuccess)
{
std::cerr << "Parsing " << strSrc;
std::cerr << " error count: " << parser->getErrorCount() <<
std::endl;
}
}
catch (const DOMException& e)
{
std::cerr << "DOM Exception parsing ";
std::cerr << strSrc;
std::cerr << " reports: ";
// was message provided?
if (e.msg)
{
// yes: display it as ascii.
char *strMsg = XMLString::transcode(e.msg);
std::cerr << strMsg << std::endl;
XMLString::release(&strMsg);
}
else
// no: just display the error code.
std::cerr << e.code << std::endl;
}
catch (const XMLException& e)
{
std::cerr << "XML Exception parsing ";
std::cerr << strSrc;
std::cerr << " reports: ";
std::cerr << e.getMessage() << std::endl;
}
catch (const SAXException& e)
{
std::cerr << "SAX Exception parsing ";
std::cerr << strSrc;
std::cerr << " reports: ";
std::cerr << e.getMessage() << std::endl;
}
catch (...)
{
std::cerr << "An exception parsing ";
std::cerr << strSrc << std::endl;
}
// did the input document parse okay?
if (bSuccess)
*ppDoc = parser->getDocument();

XMLString::release(&strSrc);
}
return bSuccess;
}

// appends the suggested file extension to the
// file path if it does not already have one.
static void massage(XercesString &wstrPath, const XMLCh *strTail, bool
bChop = false)
{
bool bTail = false;
int nDex = wstrPath.size();
while (!bTail && nDex--)
{
const XMLCh ch = wstrPath[nDex];
switch (ch)
{
case L'.':
bTail = true;
break;
case L'/':
case L'\\':
break;
default:
break;
}
}
if (!bTail)
{
wstrPath.append(strTail);
}
else if (bChop)
{
wstrPath.erase(wstrPath.begin() + nDex, wstrPath.end());
wstrPath.append(strTail);
}
}

int main(int argc, char* argv[])
{
char *src = NULL, *dst = NULL;

if (argc == 2)
{
dst = src = argv[1];
}
else if (argc == 3)
{
src = argv[1];
dst = argv[2];
}

// initialize library
XMLPlatformUtils::Initialize();
if (src && dst)
{
DOMDocument* pDoc = NULL;
XercesString wstrSrc(src), wstrDst(dst);

// massage parameters into file names with proper extension.
massage(wstrSrc, XercesString(".xml") );
massage(wstrDst, XercesString(".svg"), true);
// attempt to parse the document into a DOM object.
if ( doc2dom(wstrSrc, &pDoc) )
{
DOMDocument* pSvg = NULL;
DOMWriterImpl writer;
LocalFileFormatTarget fileTarget(wstrDst);
//StdOutFormatTarget coutTarget;

if ( pDoc->hasChildNodes() )
{
// parsed okay convert input DOM object
// into an SVG output DOM object.
dom2svg(*pDoc, XercesString("sales"), &pSvg);
// write the resulting document.
writer.setEncoding( XercesString("UTF-8") );
writer.writeNode(&fileTarget, *pSvg);
//writer.writeNode(&coutTarget, *pSvg);
}
else
std::cerr << "empty document!\n";
}
else
std::cerr << "Opening & parsing document " << src << " fails!";
}
else
{
// throw the user a clue.
std::cerr << "Usage:\n";
std::cerr << "xml2svg <in-file> <out-file>\n";
std::cerr << " -- or --\n";
std::cerr << "xml2svg <in-file>\n";
}
// cleanup library
getchar();
XMLPlatformUtils::Terminate();
return 0;
}


-MI

Loading...