1 // file : examples/cxx/tree/multiroot/driver.cxx 2 // copyright : not copyrighted - public domain 3 4 #include <memory> // std::auto_ptr 5 #include <string> 6 #include <fstream> 7 #include <iostream> 8 9 #include <xercesc/dom/DOM.hpp> 10 #include <xercesc/util/PlatformUtils.hpp> 11 12 #include <xsd/cxx/xml/string.hxx> // xml::transcode 13 14 #include "dom-parse.hxx" 15 16 #include "protocol.hxx" 17 18 using namespace std; 19 using namespace protocol; 20 21 // Parse an XML document and return a pointer to request_t which can 22 // then be tested with dynamic_cast. If your vocabulary does not have 23 // a common base type for all root element types then you can use 24 // xml_schema::type which is a base for all generated types. 25 // 26 auto_ptr<request_t> parse(istream & is,const string & id)27parse (istream& is, const string& id) 28 { 29 using namespace xercesc; 30 namespace xml = xsd::cxx::xml; 31 32 // Parse an XML instance to a DOM document using the parse() 33 // function from dom-parse.hxx. 34 // 35 xml_schema::dom::auto_ptr<DOMDocument> doc (parse (is, id, true)); 36 37 DOMElement* root (doc->getDocumentElement ()); 38 39 string ns (xml::transcode<char> (root->getNamespaceURI ())); 40 string name (xml::transcode<char> (root->getLocalName ())); 41 42 auto_ptr<request_t> r; 43 44 // We could have handled the result directly in this function 45 // instead of returning it as an opaque pointer and using 46 // dynamic_cast later to figure out which request we are dealing 47 // with. 48 // 49 if (ns == "http://www.codesynthesis.com/protocol") 50 { 51 if (name == "balance") 52 { 53 // Use the balance parsing function. 54 // 55 r.reset (balance (*doc).release ()); 56 } 57 else if (name == "withdraw") 58 { 59 // Use the withdraw parsing function. 60 // 61 r.reset (withdraw (*doc).release ()); 62 } 63 } 64 65 if (r.get () == 0) 66 cerr << "ignoring unknown request: " << ns << "#" << name << endl; 67 68 return r; 69 } 70 71 int main(int argc,char * argv[])72main (int argc, char* argv[]) 73 { 74 if (argc != 2) 75 { 76 cerr << "usage: " << argv[0] << " request.xml" << endl; 77 return 1; 78 } 79 80 int r (0); 81 82 // We need to initialize the Xerces-C++ runtime because we 83 // are doing the XML-to-DOM parsing ourselves. 84 // 85 xercesc::XMLPlatformUtils::Initialize (); 86 87 try 88 { 89 ifstream ifs; 90 ifs.exceptions (ifstream::badbit | ifstream::failbit); 91 ifs.open (argv[1]); 92 93 auto_ptr<request_t> r (parse (ifs, argv[1])); 94 95 // Let's print what we've got. 96 // 97 if (balance_t* b = dynamic_cast<balance_t*> (r.get ())) 98 { 99 cerr << "balance request for acc# " << b->account () << endl; 100 } 101 else if (withdraw_t* w = dynamic_cast<withdraw_t*> (r.get ())) 102 { 103 cerr << "withdrawal request for acc# " << w->account () << ", " 104 << "amount: " << w->amount () << endl; 105 } 106 else 107 { 108 cerr << "unknown request" << endl; 109 } 110 } 111 catch (const xml_schema::exception& e) 112 { 113 cerr << e << endl; 114 r = 1; 115 } 116 catch (const std::ios_base::failure&) 117 { 118 cerr << argv[1] << ": unable to open or read failure" << endl; 119 r = 1; 120 } 121 122 xercesc::XMLPlatformUtils::Terminate (); 123 return r; 124 } 125