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