//$Id: XML_Helper.tpp 97060 2013-04-19 19:17:11Z mitza $ #include "XML_Helper.h" #include "ace/Auto_Ptr.h" #include "ace/Log_Msg.h" #include "ace/Log_Category.h" #include "xercesc/util/XMLUniDefs.hpp" #include "xercesc/dom/DOM.hpp" #include "XML_Error_Handler.h" #include "XML_Schema_Resolver.h" #include "xercesc/framework/LocalFileFormatTarget.hpp" #include "xercesc/dom/DOM.hpp" #include "XercesString.h" #if XERCES_VERSION_MAJOR == 3 #include "xercesc/dom/DOMLSSerializer.hpp" #endif namespace XML { using xercesc::XMLException; using xercesc::XMLString; using xercesc::DOMImplementation; using xercesc::DOMImplementationRegistry; // using xercesc::DOMBuilder; using xercesc::DOMImplementationLS; using xercesc::XMLUni; using xercesc::DOMDocument; using xercesc::DOMException; using xercesc::DOMDocumentType; using xercesc::XercesDOMParser; /* template XML_Helper::XML_Helper (void) : initialized_ (false) { this->init_parser (); } */ // TODO this is stub implementation template XML_Helper::XML_Helper (Resolver *resolver, Error *eh) : initialized_ (false), resolver_ (resolver), release_resolver_(false), e_handler_ (eh), release_e_handler_ (false) { this->init_parser (); } template XML_Helper::~XML_Helper (void) { this->terminate_parser (); } template bool XML_Helper::is_initialized (void) const { return this->initialized_ == true; } template void XML_Helper::init_parser (void) { if (this->initialized_) return; // CIAO_DEBUG ((LM_TRACE, CLINFO //"XML_Helper<>::is_initialized - Initializing the Xerces runtime \n")); // Initialize the Xerces run-time try { if (!resolver_) { resolver_ = new Resolver (); release_resolver_ = true; } if (!e_handler_) { e_handler_ = new Error (); release_e_handler_ = true; } xercesc::XMLPlatformUtils::Initialize(); } catch (const XMLException& e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); throw; } catch (...) { ACELIB_DEBUG ((LM_DEBUG, "(%P|%t) Some other exception, returning\n")); return; } // Instantiate the DOM parser. static const XMLCh gLS[] = { xercesc::chLatin_L, xercesc::chLatin_S, xercesc::chNull }; // Get an implementation of the Load-Store (LS) interface // and cache it for later use impl_ = DOMImplementationRegistry::getDOMImplementation(gLS); this->initialized_ = true; return; } template XERCES_CPP_NAMESPACE::DOMDocument * XML_Helper::create_dom (const ACE_TCHAR *root, const ACE_TCHAR *ns, DOMDocumentType *doctype) const { if (root == 0 || ns == 0) return 0; return this->impl_->createDocument (XStr (ns), XStr (root), doctype); } template XERCES_CPP_NAMESPACE::DOMDocumentType * XML_Helper::create_doctype (const ACE_TCHAR *qn, const ACE_TCHAR *pid, const ACE_TCHAR *sid) const { return this->impl_->createDocumentType (XStr (qn), XStr (pid), XStr (sid)); } template XERCES_CPP_NAMESPACE::DOMDocument * XML_Helper::create_dom (const ACE_TCHAR *url) const { if (url == 0) return 0; try { if (this->parser_.get () == 0) this->parser_.reset ((new xercesc::XercesDOMParser ())); // Perform Namespace processing. this->parser_->setDoNamespaces (true); // Discard comment nodes in the document this->parser_->setCreateCommentNodes (false); // Disable datatype normalization. The XML 1.0 attribute value // normalization always occurs though. // this->parser_->setFeature (XMLUni::fgDOMDatatypeNormalization, true); // Do not create EntityReference nodes in the DOM tree. No // EntityReference nodes will be created, only the nodes // corresponding to their fully expanded sustitution text will be // created. this->parser_->setCreateEntityReferenceNodes (false); // Perform Validation this->parser_->setValidationScheme (xercesc::AbstractDOMParser::Val_Always); // Do not include ignorable whitespace in the DOM tree. this->parser_->setIncludeIgnorableWhitespace (false); // Enable the parser's schema support. this->parser_->setDoSchema (true); // Enable full schema constraint checking, including checking which // may be time-consuming or memory intensive. Currently, particle // unique attribution constraint checking and particle derivation // restriction checking are controlled by this option. this->parser_->setValidationSchemaFullChecking (true); // The parser will treat validation error as fatal and will exit. this->parser_->setValidationConstraintFatal (true); this->parser_->setErrorHandler (e_handler_); this->parser_->setEntityResolver (resolver_); this->parser_->parse (ACE_TEXT_ALWAYS_CHAR (url)); if (e_handler_ && e_handler_->getErrors ()) return 0; return this->parser_->getDocument (); } catch (const DOMException& e) { const unsigned int maxChars = 2047; XMLCh errText[maxChars + 1]; if (DOMImplementation::loadDOMExceptionMsg (e.code, errText, maxChars)) { char* message = XMLString::transcode (errText); ACE_Auto_Basic_Array_Ptr cleanup_message (message); } return 0; } catch (const XMLException& e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); throw 0; } catch (...) { ACELIB_DEBUG ((LM_DEBUG, "(%P|%t) Caught an unknown exception\n")); throw; } return 0; } template void XML_Helper::terminate_parser (void) { if (!this->initialized_) return; try { if (release_resolver_ && resolver_) { delete resolver_; resolver_ = 0; } if (release_e_handler_ && e_handler_) { delete e_handler_; e_handler_ = 0; } this->parser_.reset (0); this->impl_ = 0; xercesc::XMLPlatformUtils::Terminate(); } catch (const XMLException& e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); throw; } this->initialized_ = false; return; } template Resolver & XML_Helper::get_resolver (void) { if (!this->resolver_) throw std::exception (); return *this->resolver_; } template Error & XML_Helper::get_error_handler (void) { if (!this->e_handler_) throw std::exception (); return *this->e_handler_; } template bool XML_Helper::write_DOM (XERCES_CPP_NAMESPACE::DOMDocument *doc, const ACE_TCHAR *file) const { try { bool retn; #if XERCES_VERSION_MAJOR == 3 XERCES_CPP_NAMESPACE::DOMLSSerializer *serializer (impl_->createLSSerializer ()); XERCES_CPP_NAMESPACE::DOMConfiguration *ser_config (serializer->getDomConfig ()); XERCES_CPP_NAMESPACE::DOMLSOutput *output (impl_->createLSOutput ()); if (ser_config->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)) ser_config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true); XMLFormatTarget *format_target = new XERCES_CPP_NAMESPACE::LocalFileFormatTarget (ACE_TEXT_ALWAYS_CHAR (file)); output->setByteStream (format_target); retn = serializer->write (doc, output); output->release (); serializer->release (); return retn; #else std::auto_ptr writer (impl_->createDOMWriter()); if (writer->canSetFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true)) writer->setFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true); std::auto_ptr ft (new xercesc::LocalFileFormatTarget(ACE_TEXT_ALWAYS_CHAR (file))); retn = writer->writeNode(ft.get (), *doc); return retn; #endif } catch (const xercesc::XMLException &e) { char* message = XMLString::transcode (e.getMessage()); ACE_Auto_Basic_Array_Ptr cleanup_message (message); char* name = XMLString::transcode (e.getType()); ACE_Auto_Basic_Array_Ptr cleanup_name (name); ACELIB_ERROR ((LM_ERROR, "Caught exception while serializing DOM to file.\n" "Name: %C\n" "Message: %C\n" "SrcFile: %C\n" "SrcLine: %C\n", name, message, e.getSrcFile (), e.getSrcLine ())); return false; } } }