Meena Vyas wrote:
I have a sample program for now it just prints out a given input xml
file. Although the element's value (in characters function) gets printed
properly, startElement and endElement functions are unable to print the
name of the element properly.
Here is my test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<server>
<temp-path>/tmp/https-test-8b90356b</temp-path>
</server>
Output I get when I use Xerces C 3.0.1 :
#CC -g test.cpp -I/opt/xerces-c/3.0.1/include/
-L/opt/xerces-c/3.0.1/lib -lxerces-c -DSOLARIS
env - LD_LIBRARY_PATH=/opt/xerces-c/3.0.1/lib ./a.out
----
<>
<>/tmp/https-test-8b90356b</>
</>
----
Note that when I use Xerecs C 2.8, the same program prints the correct
XML :
#CC test.cpp -I/opt/xerces-c/2.8.0/include/
-L/opt/xerces-c/2.8.0/lib -lxerces-c
env - LD_LIBRARY_PATH=/opt/xerces-c/2.8.0/lib ./a.out
----
<server>
<temp-path>/tmp/https-test-8b90356b<temp-path/>
<server/>
----
cat test.cpp :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "xercesc/util/BinInputStream.hpp"
#include "xercesc/util/XMLString.hpp"
#include "xercesc/util/XercesDefs.hpp"
#include "xercesc/sax/InputSource.hpp"
#include "xercesc/sax2/Attributes.hpp"
#include "xercesc/sax2/DefaultHandler.hpp"
#include "xercesc/sax2/SAX2XMLReader.hpp"
#include "xercesc/sax2/XMLReaderFactory.hpp"
#include "xercesc/util/PlatformUtils.hpp"
using namespace XERCES_CPP_NAMESPACE;
class CString {
public:
CString(const XMLCh *string);
CString(const XMLCh *string, int len);
~CString() { if (cstring != NULL) free(cstring); }
inline const char * getStringValue() const { return cstring; }
private:
void init(const char *string) { cstring = strdup(string); }
char *cstring;
};
CString::CString(const XMLCh *string)
{
if (string != NULL) {
char *transcoded = XMLString::transcode(string);
init(transcoded);
XMLString::release(&transcoded);
} else {
init("");
}
}
CString::CString(const XMLCh *string, int len)
{
if (string != NULL) {
char *transcoded = new char[len + 1];
XMLString::transcode(string, transcoded, len);
init(transcoded);
delete [] transcoded;
} else {
init("");
}
}
class MySAXHandler : public DefaultHandler {
public:
MySAXHandler() { }
void startElement(const XMLCh *const uri, const XMLCh *const
localname, const XMLCh *const qname, const Attributes& attrs);
void endElement(const XMLCh *const uri, const XMLCh *const
localname, const XMLCh *const qname);
void characters(const XMLCh *const s, const unsigned len);
void warning(const SAXParseException& e) { }
void error(const SAXParseException& e) { }
void fatalError(const SAXParseException& e) { }
};
void MySAXHandler::startElement(const XMLCh *const uri, const XMLCh
*const localname, const XMLCh *const qn0me, const Attributes& attrs)
{
CString name(localname);
printf("\t<%s>", name.getStringValue());
}
Depending on how you configure the parser, you may or may not get a
value for the localname parameter. There were some long-standing bugs
that provided inconsistent behavior in 2.8 that were fixed in 3.0.
Please use the qname parameter, rather than the localname parameter.
void MySAXHandler::endElement(const XMLCh *const uri, const XMLCh
*const localname, const XMLCh *const qname)
{
CString name(localname);
printf("<%s/>", name.getStringValue());
}
void MySAXHandler::characters(const XMLCh *const s, const unsigned len)
{
CString *cs = new CString(s, len);
const char *arr = cs->getStringValue();
printf("%s", arr);
}
The prototype for the ContentHandler::characters() changed between
Xerces-C 2.8 and 3.0.1, so your characters() overload will never be
called. You will need some conditional compilation ifdefs to deal with this:
#if XERCES_VERSION_MAJOR < 3
void MySAXHandler::characters(const XMLCh *const s, const unsigned len)
#else
void MySAXHandler::characters(const XMLCh *const s, const XMLSize_t len)
#endif
Dave