00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 #ifndef VCSN_XML_XERCES_PARSER_HXX
00018 # define VCSN_XML_XERCES_PARSER_HXX
00019 
00029 # include <fstream>
00030 
00031 # define parser_set_property(prop) \
00032       if (parser->canSetFeature(XMLUni::prop, true)) \
00033         parser->setFeature(XMLUni::prop, true);
00034 
00035 # define parser_set_value(prop, value) \
00036         parser->setProperty(XMLUni::prop, value);
00037 
00038 
00039 namespace vcsn
00040 {
00041   namespace xml
00042   {
00043 
00044     static inline std::string get_xsd_path ()
00045     {
00046       { 
00047         const char* xsd_env = getenv ("VCSN_XSD_PATH");
00048         if (xsd_env)
00049           return xsd_env;
00050       }
00051       static const char* possible_xsds[] =
00052         { "vaucanson.xsd", VCSN_XSD_PATH, 0 };
00053       const char**       result;
00054       for (result = possible_xsds; *result; ++result)
00055       {
00056         std::ifstream is (*result);
00057         if (is.good ())
00058           break;
00059       }
00060       if (*result)
00061         return *result;
00062       FAIL ("Error: XSD file not found. Please either set VCSN_XSD_PATH\n"
00063             "to the path of `vaucanson.xsd', put this file in the current\n"
00064             "directory or put it in " VCSN_XSD_PATH ".");
00065       return "";
00066     }
00067 
00068     template <class IStream>
00069     xercesc::DOMDocument*
00070     xerces_parser::loaddocument(xercesc::DOMBuilder* parser, IStream& is)
00071     {
00072       using namespace xercesc;
00073 
00074       parser_set_property(fgDOMValidation);
00075       parser_set_property(fgDOMNamespaces);
00076       parser_set_property(fgDOMDatatypeNormalization);
00077       parser_set_property(fgXercesSchema);
00078       parser_set_property(fgXercesUseCachedGrammarInParse);
00079       parser_set_property(fgXercesCacheGrammarFromParse);
00080 
00081       XMLCh* xsd_link =
00082         STR2XML(("http://vaucanson.lrde.epita.fr " + get_xsd_path ()).c_str ());
00083       parser_set_value(fgXercesSchemaExternalSchemaLocation, xsd_link);
00084 
00085       
00086 
00087       myDOMErrorHandler* err = new myDOMErrorHandler();
00088       parser->setErrorHandler(err);
00089 
00090       DOMDocument* doc;
00091       try
00092         {
00093           CxxInputSource        i (&is);
00094           Wrapper4InputSource   w (&i, false);
00095           doc = parser->parse(w);
00096         }
00097       catch (const XMLException& e)
00098         {
00099           FAIL(std::string ("XML exception: ") + xml2str(e.getMessage()));
00100         }
00101       catch (const DOMException& e)
00102         {
00103           FAIL(std::string ("DOM exception: ") + xml2str(e.msg));
00104         }
00105       catch (...)
00106         {
00107           FAIL("Unknown exception caught.");
00108         }
00109 
00110       if (err->has_error())
00111         FAIL(err->get_msg());
00112       
00113       delete err;
00114       return doc;
00115     }
00116 
00117     template <class IStream>
00118     xercesc::DOMElement*
00119     xerces_parser::stream_parser(IStream& is)
00120     {
00121       using namespace xercesc;
00122 
00123       DOMImplementation* impl =
00124         DOMImplementationRegistry::getDOMImplementation(STR2XML("LS"));
00125       DOMBuilder* parser = static_cast<DOMImplementationLS*> (impl)
00126         ->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
00127 
00128       DOMDocument* doc = loaddocument(parser, is);
00129 
00130       DOMNodeList* nodelist;
00131 
00132       nodelist = doc->getElementsByTagName(STR2XML("session"));
00133       if (! nodelist->getLength())
00134         nodelist = doc->getElementsByTagName(STR2XML("automaton"));
00135       if (! nodelist->getLength())
00136         nodelist = doc->getElementsByTagName(STR2XML("transducer"));
00137       if (! nodelist->getLength())
00138         FAIL("Cannot find any appropriate root.");
00139 
00140       DOMElement* node = static_cast<DOMElement*>(nodelist->item(0));
00141       return node;
00142     }
00143 
00144   } 
00145 
00146 } 
00147 
00148 # undef parser_set_property
00149 # undef parser_set_value
00150 
00151 
00152 #endif // ! VCSN_XML_XERCES_PARSER_HXX