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 namespace vcsn
00032 {
00033 namespace xml
00034 {
00035
00036 static inline std::string get_xsd_path ()
00037 {
00038
00039 const char* path = getenv ("VCSN_DATA_PATH");
00040 const char* xsd = "vaucanson.xsd";
00041 if (path == 0)
00042 path = VCSN_DATA_PATH;
00043 std::string file = std::string (path) + "/" + xsd;
00044 if (std::ifstream (file.c_str ()).good ())
00045 return file;
00046 FAIL (std::string ("Error: cannot open `") + path + "/" + xsd + "'.\n"
00047 "Please set VCSN_DATA_PATH to the Vaucanson data directory,\n"
00048 "containing `" + xsd + "'.");
00049 return "";
00050 }
00051
00052 template <class IStream>
00053 xercesc::DOMDocument*
00054 xerces_parser::load_document(xercesc::DOMBuilder* parser, IStream& is)
00055 {
00056 using namespace xercesc;
00057
00058 # define PARSER_SET_FEATURE(prop) \
00059 if (parser->canSetFeature(XMLUni::prop, true)) \
00060 parser->setFeature(XMLUni::prop, true);
00061
00062 PARSER_SET_FEATURE(fgDOMValidation);
00063 PARSER_SET_FEATURE(fgDOMNamespaces);
00064 PARSER_SET_FEATURE(fgDOMDatatypeNormalization);
00065 PARSER_SET_FEATURE(fgXercesSchema);
00066 PARSER_SET_FEATURE(fgXercesUseCachedGrammarInParse);
00067 PARSER_SET_FEATURE(fgXercesCacheGrammarFromParse);
00068
00069 # undef PARSER_SET_FEATURE
00070
00071
00072 # define PARSER_SET_PROPERTY(prop, value) \
00073 parser->setProperty(XMLUni::prop, value);
00074
00075 PARSER_SET_PROPERTY(fgXercesSchemaExternalSchemaLocation,
00076 transcode(VCSN_XMLNS " " + get_xsd_path ()));
00077
00078 # undef PARSER_SET_PROPERTY
00079
00080
00081 myDOMErrorHandler* err = new myDOMErrorHandler();
00082 parser->setErrorHandler(err);
00083
00084 DOMDocument* doc;
00085 try
00086 {
00087 CxxInputSource i (&is);
00088 Wrapper4InputSource w (&i, false);
00089 doc = parser->parse(w);
00090 }
00091 catch (const XMLException& e)
00092 {
00093 FAIL(std::string ("XML exception: ") + xml2str(e.getMessage()));
00094 }
00095 catch (const DOMException& e)
00096 {
00097 FAIL(std::string ("DOM exception: ") + xml2str(e.msg));
00098 }
00099 catch (...)
00100 {
00101 FAIL("Unknown exception caught.");
00102 }
00103
00104 if (err->has_error())
00105 FAIL(err->get_msg());
00106
00107 delete err;
00108 return doc;
00109 }
00110
00111 template <class IStream>
00112 xercesc::DOMElement*
00113 xerces_parser::stream_parser(IStream& is)
00114 {
00115 using namespace xercesc;
00116
00117 DOMImplementation* impl =
00118 DOMImplementationRegistry::getDOMImplementation(transcode("LS"));
00119 DOMBuilder* parser = static_cast<DOMImplementationLS*> (impl)
00120 ->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
00121
00122 DOMDocument* doc = load_document(parser, is);
00123
00124 DOMNodeList* nodelist = doc->getElementsByTagName(transcode("session"));
00125 if (! nodelist->getLength())
00126 nodelist = doc->getElementsByTagName(transcode("automaton"));
00127 if (! nodelist->getLength())
00128 FAIL("Cannot find any appropriate root.");
00129
00130 return static_cast<DOMElement*>(nodelist->item(0));
00131 }
00132
00133 }
00134
00135 }
00136
00137 #endif // ! VCSN_XML_XERCES_PARSER_HXX