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

Reply via email to