|
I need to convert a DOM_Document to a CString for a
Web request. Instead of hardcoding the string, I am trying to create it with
Xerces.
Somebody over here mentioned that he was able to
obtain a char* with overloading method from DOMPrint while using strstream
instead of ostream, and extracting the string by calling str() on the stream. I
did that. The XML document prints out to the console just the way I need
it. But what ends up in a string does not look any good. It looks like "����1".
Was anybody here able to obtain a string successfully? If yes, can somebody
provide a working code sample?
Writing to a file would do it. If I write to a file by using DOMPrint, I get an empty file. Also, to those who say "Use
DomSerializer". Was anybody here was even able to compile it? It does not
compile on MVS 6.0. You will get 12 errors.
Respectfully,
Anton Spektorov
e-mail: [EMAIL PROTECTED] Here is my code:
/**
* This File is supposed to generate a properly formatted XML Document */ ///
// Includes /// #include "stdafx.h"
#include <xercesc/util/PlatformUtils.hpp> #include <xercesc/util/XMLString.hpp> #include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOM_NODE.hpp> #include <iostream.h> #include <stdio.h> #include<fstream.h> #include <stdlib.h> #include "StringWriter.cpp" #include <strstrea.h> /**
* Main Method */ int main(int argc, char* argv[]) { /**
* Initialize Xml Utilities */ try
{ XMLPlatformUtils::Initialize(); } catch(const XMLException&
toCatch)
{ char *pMsg = XMLString::transcode(toCatch.getMessage()); cerr << "Error during Xerces-c Initialization.\n" << " Exception message:" << pMsg; delete [] pMsg; } DOMPrintFormatTarget* formatTarget; try { DOM_DOMImplementation impl;
DOM_DocumentType dt=impl.createDocumentType("pp.request","-//IMALL//DTD PUREPAYMENTS 1.0//EN","http://www.purepayments.com/dtd/purepayments.dtd"); DOM_Document doc = impl.createDocument( "-//IMALL//DTD PUREPAYMENTS 1.0//EN" , // root element namespace URI. "pp.request",// root element name dt); // document type object (DTD). doc.createXMLDecl("","",false); DOM_Element rootElement =
doc.getDocumentElement();
rootElement.setAttribute("merchant","1001");
rootElement.setAttribute("password","password"); DOM_Element authElement =
doc.createElement("pp.auth");
authElement.setAttribute("ordernumber","10000"); authElement.setAttribute("shippingcost","0.0USD"); authElement.setAttribute("taxamount","0.0USD"); rootElement.appendChild(authElement); DOM_Element ccElement=doc.createElement("pp.creditcard");
ccElement.setAttribute("number","4111111111111111"); ccElement.setAttribute("expiration","12/05"); authElement.appendChild(ccElement); DOM_Element shipAddrElement=doc.createElement("pp.address"); shipAddrElement.setAttribute("type","shipping");
shipAddrElement.setAttribute("fullname","Anton Test");
shipAddrElement.setAttribute("address1","555 Steeple Chase"); shipAddrElement.setAttribute("address2",""); shipAddrElement.setAttribute("city","Jacksonville"); shipAddrElement.setAttribute("state","NC"); shipAddrElement.setAttribute("zip","28545"); shipAddrElement.setAttribute("country","US"); authElement.appendChild(shipAddrElement); DOM_Element
lineItemElement=doc.createElement("pp.lineitem");
lineItemElement.setAttribute("sku","sku_1"); lineItemElement.setAttribute("description","Good Product"); lineItemElement.setAttribute("quantity","1"); lineItemElement.setAttribute("taxrate","1"); lineItemElement.setAttribute("unitprice","11.00USD"); authElement.appendChild(lineItemElement); formatTarget = new DOMPrintFormatTarget();
if (gEncodingName ==
0)
{ DOMString encNameStr("UTF-8"); DOM_Node aNode = doc.getFirstChild(); if (aNode.getNodeType() == DOM_Node::XML_DECL_NODE) { DOMString aStr = ((DOM_XMLDecl &)aNode).getEncoding(); if (aStr != "") { encNameStr = aStr; } } unsigned int lent = encNameStr.length(); gEncodingName = new XMLCh[lent + 1]; XMLString::copyNString(gEncodingName, encNameStr.rawBuffer(), lent); gEncodingName[lent] = 0; }
try
{ gFormatter = new XMLFormatter(gEncodingName, formatTarget, XMLFormatter::NoEscapes, gUnRepFlags); char* value=0; strstream TwoWayStream; TwoWayStream << "xml="<< doc << "\0"; value=TwoWayStream.str(); fstream filestr;
filestr.open ("test.txt", fstream::out); filestr << value; delete [] value; filestr.close(); } catch (XMLException& e) { cerr << "An error occurred during creation of output transcoder. Msg is:" << endl << DOMString(e.getMessage()) << endl; } }
catch (const XMLException& e)
{ cerr << "An error occured during parsing\n Message: " << DOMString(e.getMessage()) << endl; } catch (const DOM_DOMException& e) { cerr << "A DOM error occured during parsing\n DOMException code: " << e.code << endl; } catch (...)
{ cerr << "An error occured during parsing\n " << endl; } delete formatTarget; delete gFormatter; /**
* Kill memory leaks */ XMLPlatformUtils::Terminate(); return 0;
} /**
* StringWriter.cpp is a DOMPrint w/out main */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include <xercesc/util/PlatformUtils.hpp> #include <xercesc/util/XMLString.hpp> #include <xercesc/util/XMLUniDefs.hpp> #include <xercesc/framework/XMLFormatter.hpp> #include <xercesc/util/TranscodingException.hpp> #include <xercesc/dom/DOM_DOMException.hpp> #include <xercesc/parsers/DOMParser.hpp>
#include <xercesc/dom/DOM.hpp> #include "DOMTreeErrorReporter.hpp" #include <string.h> #include <stdlib.h> // --------------------------------------------------------------------------- // Local const data // // Note: This is the 'safe' way to do these strings. If you compiler supports // L"" style strings, and portability is not a concern, you can use // those types constants directly. // --------------------------------------------------------------------------- static const XMLCh gEndElement[] = { chOpenAngle, chForwardSlash, chNull }; static const XMLCh gEndPI[] = { chQuestion, chCloseAngle, chNull}; static const XMLCh gStartPI[] = { chOpenAngle, chQuestion, chNull }; static const XMLCh gXMLDecl1[] = { chOpenAngle, chQuestion, chLatin_x, chLatin_m, chLatin_l , chSpace, chLatin_v, chLatin_e, chLatin_r, chLatin_s, chLatin_i , chLatin_o, chLatin_n, chEqual, chDoubleQuote, chNull }; static const XMLCh gXMLDecl2[] = { chDoubleQuote, chSpace, chLatin_e, chLatin_n, chLatin_c , chLatin_o, chLatin_d, chLatin_i, chLatin_n, chLatin_g, chEqual , chDoubleQuote, chNull }; static const XMLCh gXMLDecl3[] = { chDoubleQuote, chSpace, chLatin_s, chLatin_t, chLatin_a , chLatin_n, chLatin_d, chLatin_a, chLatin_l, chLatin_o , chLatin_n, chLatin_e, chEqual, chDoubleQuote, chNull }; static const XMLCh gXMLDecl4[] = { chDoubleQuote, chQuestion, chCloseAngle , chLF, chNull }; static const XMLCh gStartCDATA[]
=
{ chOpenAngle, chBang, chOpenSquare, chLatin_C, chLatin_D, chLatin_A, chLatin_T, chLatin_A, chOpenSquare, chNull }; static const XMLCh gEndCDATA[] =
{ chCloseSquare, chCloseSquare, chCloseAngle, chNull }; static const XMLCh gStartComment[] = { chOpenAngle, chBang, chDash, chDash, chNull }; static const XMLCh gEndComment[] =
{ chDash, chDash, chCloseAngle, chNull }; static const XMLCh gStartDoctype[] =
{ chOpenAngle, chBang, chLatin_D, chLatin_O, chLatin_C, chLatin_T, chLatin_Y, chLatin_P, chLatin_E, chSpace, chNull }; static const XMLCh gPublic[] = { chLatin_P, chLatin_U, chLatin_B, chLatin_L, chLatin_I, chLatin_C, chSpace, chDoubleQuote, chNull }; static const XMLCh gSystem[] = { chLatin_S, chLatin_Y, chLatin_S, chLatin_T, chLatin_E, chLatin_M, chSpace, chDoubleQuote, chNull }; static const XMLCh gStartEntity[] = { chOpenAngle, chBang, chLatin_E, chLatin_N, chLatin_T, chLatin_I, chLatin_T, chLatin_Y, chSpace, chNull }; static const XMLCh gNotation[] = { chLatin_N, chLatin_D, chLatin_A, chLatin_T, chLatin_A, chSpace, chDoubleQuote, chNull }; //
---------------------------------------------------------------------------
// Local classes // --------------------------------------------------------------------------- class DOMPrintFormatTarget : public
XMLFormatTarget
{ public: DOMPrintFormatTarget() {}; ~DOMPrintFormatTarget() {}; //
-----------------------------------------------------------------------
// Implementations of the format target interface // ----------------------------------------------------------------------- void writeChars(const XMLByte* const
toWrite,
const unsigned int count, XMLFormatter * const formatter) { // Surprisingly, Solaris was the only platform on which // required the char* cast to print out the string correctly. // Without the cast, it was printing the pointer value in hex. // Quite annoying, considering every other platform printed // the string with the explicit cast to char* below. cout.write((char *) toWrite, (int) count); }; private:
// ----------------------------------------------------------------------- // Unimplemented methods. // ----------------------------------------------------------------------- DOMPrintFormatTarget(const DOMPrintFormatTarget& other); void operator=(const DOMPrintFormatTarget& rhs); }; //
---------------------------------------------------------------------------
// Local data // // gXmlFile // The path to the file to parser. Set via command line. // // gDoNamespaces // Indicates whether namespace processing should be done. // // gDoSchema // Indicates whether schema processing should be done. // // gSchemaFullChecking // Indicates whether full schema constraint checking should be done. // // gDoCreate // Indicates whether entity reference nodes needs to be created or not // Defaults to false // // gEncodingName // The encoding we are to output in. If not set on the command line, // then it is defaults to the encoding of the input XML file. // // gValScheme // Indicates what validation scheme to use. It defaults to 'auto', but // can be set via the -v= command. // // --------------------------------------------------------------------------- static char* gXmlFile = 0; static bool gDoNamespaces = false; static bool gDoSchema = false; static bool gSchemaFullChecking = false; static bool gDoCreate = false; static XMLCh* gEncodingName = 0; static XMLFormatter::UnRepFlags gUnRepFlags = XMLFormatter::UnRep_CharRef; static DOMParser::ValSchemes gValScheme = DOMParser::Val_Never; static XMLFormatter* gFormatter = 0; //
---------------------------------------------------------------------------
// Forward references // --------------------------------------------------------------------------- ostream& operator<<(ostream& target, const DOMString& toWrite); ostream& operator<<(ostream& target, DOM_Node& toWrite); XMLFormatter& operator<< (XMLFormatter& strm, const DOMString& s); //
---------------------------------------------------------------------------
// ostream << DOM_Node // // Stream out a DOM node, and, recursively, all of its children. This // function is the heart of writing a DOM tree out as XML source. Give it // a document node and it will do the whole thing. // --------------------------------------------------------------------------- ostream& operator<<(ostream& target, DOM_Node& toWrite) { // Get the name and value out for convenience DOMString nodeName = toWrite.getNodeName(); DOMString nodeValue = toWrite.getNodeValue(); unsigned long lent = nodeValue.length(); switch (toWrite.getNodeType())
{ case DOM_Node::TEXT_NODE: { gFormatter->formatBuf(nodeValue.rawBuffer(), lent, XMLFormatter::CharEscapes); break; } case DOM_Node::PROCESSING_INSTRUCTION_NODE : { *gFormatter << XMLFormatter::NoEscapes << gStartPI << nodeName; if (lent > 0) { *gFormatter << chSpace << nodeValue; } *gFormatter << XMLFormatter::NoEscapes << gEndPI; break; } case DOM_Node::DOCUMENT_NODE : { DOM_Node
child =
toWrite.getFirstChild();
while( child != 0) { target << child; // add linefeed in requested output encoding *gFormatter << chLF; target << flush; child = child.getNextSibling(); } break; } case DOM_Node::ELEMENT_NODE : { // The name has to be representable without any escapes *gFormatter << XMLFormatter::NoEscapes << chOpenAngle << nodeName; //
Output the element start tag.
//
Output any attributes on this
element
DOM_NamedNodeMap attributes = toWrite.getAttributes(); int attrCount = attributes.getLength(); for (int i = 0; i < attrCount; i++) { DOM_Node attribute = attributes.item(i);
//
// Again the name has to be completely representable. But the // attribute can have refs and requires the attribute style // escaping. // *gFormatter << XMLFormatter::NoEscapes << chSpace << attribute.getNodeName() << chEqual << chDoubleQuote << XMLFormatter::AttrEscapes << attribute.getNodeValue() << XMLFormatter::NoEscapes << chDoubleQuote; }
//
// Test for the presence of children, which includes both // text content and nested elements. // DOM_Node child = toWrite.getFirstChild(); if (child != 0) { // There are children. Close start-tag, and output children. // No escapes are legal here *gFormatter << XMLFormatter::NoEscapes << chCloseAngle;
while( child !=
0)
{ target << child; child = child.getNextSibling(); }
//
// Done with children. Output the end tag. // *gFormatter << XMLFormatter::NoEscapes << gEndElement << nodeName << chCloseAngle; } else { // // There were no children. Output the short form close of // the element start tag, making it an empty-element tag. // *gFormatter << XMLFormatter::NoEscapes << chForwardSlash << chCloseAngle; } break; } case DOM_Node::ENTITY_REFERENCE_NODE: { DOM_Node child; #if 0 for (child = toWrite.getFirstChild(); child != 0; child = child.getNextSibling()) { target << child; } #else // // Instead of printing the refernece tree // we'd output the actual text as it appeared in the xml file. // This would be the case when -e option was chosen // *gFormatter << XMLFormatter::NoEscapes << chAmpersand << nodeName << chSemiColon; #endif break; } case DOM_Node::CDATA_SECTION_NODE: { *gFormatter << XMLFormatter::NoEscapes << gStartCDATA << nodeValue << gEndCDATA; break; } case DOM_Node::COMMENT_NODE: { *gFormatter << XMLFormatter::NoEscapes << gStartComment << nodeValue << gEndComment; break; } case DOM_Node::DOCUMENT_TYPE_NODE: { DOM_DocumentType doctype = (DOM_DocumentType &)toWrite;;
*gFormatter << XMLFormatter::NoEscapes <<
gStartDoctype
<< nodeName;
DOMString id =
doctype.getPublicId();
if (id != 0) { *gFormatter << XMLFormatter::NoEscapes << chSpace << gPublic << id << chDoubleQuote; id = doctype.getSystemId(); if (id != 0) { *gFormatter << XMLFormatter::NoEscapes << chSpace << chDoubleQuote << id << chDoubleQuote; } } else { id = doctype.getSystemId(); if (id != 0) { *gFormatter << XMLFormatter::NoEscapes << chSpace << gSystem << id << chDoubleQuote; } } id =
doctype.getInternalSubset();
if (id !=0) *gFormatter << XMLFormatter::NoEscapes << chOpenSquare << id << chCloseSquare;
*gFormatter << XMLFormatter::NoEscapes <<
chCloseAngle;
break; } case DOM_Node::ENTITY_NODE: { *gFormatter << XMLFormatter::NoEscapes << gStartEntity << nodeName;
DOMString id = ((DOM_Entity
&)toWrite).getPublicId();
if (id != 0) *gFormatter << XMLFormatter::NoEscapes << gPublic << id << chDoubleQuote; id =
((DOM_Entity
&)toWrite).getSystemId();
if (id != 0) *gFormatter << XMLFormatter::NoEscapes << gSystem << id << chDoubleQuote; id =
((DOM_Entity
&)toWrite).getNotationName();
if (id != 0) *gFormatter << XMLFormatter::NoEscapes << gNotation << id << chDoubleQuote;
*gFormatter << XMLFormatter::NoEscapes << chCloseAngle <<
chLF;
break;
} case DOM_Node::XML_DECL_NODE: { DOMString str;
*gFormatter << gXMLDecl1 << ((DOM_XMLDecl
&)toWrite).getVersion();
*gFormatter << gXMLDecl2 << gEncodingName;
str =
((DOM_XMLDecl
&)toWrite).getStandalone();
if (str != 0) *gFormatter << gXMLDecl3 << str;
*gFormatter << gXMLDecl4;
break;
} default: cerr << "Unrecognized node type = " << (long)toWrite.getNodeType() << endl; } return target; } //
---------------------------------------------------------------------------
// ostream << DOMString // // Stream out a DOM string. Doing this requires that we first transcode // to char * form in the default code page for the system // --------------------------------------------------------------------------- ostream& operator<< (ostream& target, const DOMString& s) { char *p = s.transcode(); target << p; delete [] p; return target; } XMLFormatter& operator<< (XMLFormatter& strm, const DOMString& s) { unsigned int lent = s.length(); if (lent <= 0)
return strm; XMLCh* buf = new XMLCh[lent +
1];
XMLString::copyNString(buf, s.rawBuffer(), lent); buf[lent] = 0; strm << buf; delete [] buf; return strm; } /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xerces" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache\@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation, and was * originally based on software copyright (c) 1999, International * Business Machines, Inc., http://www.ibm.com . For more information * on the Apache Software Foundation, please see * <http://www.apache.org/>. */ /*
* $Log: DOMTreeErrorReporter.hpp,v $ * Revision 1.7 2002/02/01 22:35:33 peiyongz * sane_include * * Revision 1.6 2001/05/11 13:24:53 tng * Copyright update. * * Revision 1.5 2001/05/04 19:01:07 tng * DOMPrint fix. Check error before continuing. * * Revision 1.4 2000/03/02 19:53:40 roddey * This checkin includes many changes done while waiting for the * 1.1.0 code to be finished. I can't list them all here, but a list is * available elsewhere. * * Revision 1.3 2000/02/06 07:47:18 rahulj * Year 2K copyright swat. * * Revision 1.2 1999/12/03 00:14:53 andyh * Removed transcoding stuff, replaced with DOMString::transcode. * * Tweaked xml encoding= declaration to say ISO-8859-1. Still wrong, * but not as wrong as utf-8 * * Revision 1.1.1.1 1999/11/09 01:09:51 twl * Initial checkin * * Revision 1.4 1999/11/08 20:43:36 rahul * Swat for adding in Product name and CVS comment log variable. * */ #include <xercesc/util/XercesDefs.hpp>
#include <xercesc/sax/ErrorHandler.hpp> #include <iostream.h> class DOMTreeErrorReporter : public
ErrorHandler
{ public: // ----------------------------------------------------------------------- // Constructors and Destructor // ----------------------------------------------------------------------- DOMTreeErrorReporter() : fSawErrors(false) { } ~DOMTreeErrorReporter()
{ } //
-----------------------------------------------------------------------
// Implementation of the error handler interface // ----------------------------------------------------------------------- void warning(const SAXParseException& toCatch); void error(const SAXParseException& toCatch); void fatalError(const SAXParseException& toCatch); void resetErrors(); //
-----------------------------------------------------------------------
// Getter methods // ----------------------------------------------------------------------- bool getSawErrors() const; //
-----------------------------------------------------------------------
// Private data members // // fSawErrors // This is set if we get any errors, and is queryable via a getter // method. Its used by the main code to suppress output if there are // errors. // ----------------------------------------------------------------------- bool fSawErrors; }; inline bool DOMTreeErrorReporter::getSawErrors()
const
{ return fSawErrors; } |
