00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "xmlconfigfile.h"
00024 #include "xercesmanager.h"
00025 #include "xercesutils.h"
00026
00027 #include <pathan/XPathEvaluator.hpp>
00028 #include <pathan/XPathExpression.hpp>
00029 #include <pathan/XPathNSResolver.hpp>
00030 #include <pathan/XPathResult.hpp>
00031 #include <xercesc/sax/SAXParseException.hpp>
00032
00033 #include <cassert>
00034
00035 using namespace sheep;
00036 using namespace std;
00037 using namespace xercesc;
00038
00039 XMLConfigFile::XMLConfigFile(const string &filename,
00040 ErrorHandler *error_handler )
00041 {
00042 initialize(
00043 filename,
00044 "",
00045 error_handler
00046 );
00047 }
00048
00049 XMLConfigFile::XMLConfigFile(const string &filename,
00050 const string &schema_filename,
00051 ErrorHandler *error_handler )
00052 {
00053 initialize(
00054 filename,
00055 schema_filename,
00056 error_handler
00057 );
00058 }
00059
00060 XMLConfigFile::~XMLConfigFile() {
00061 delete m_nsresolver;
00062 delete m_evaluator;
00063 delete m_parser;
00064
00065 XercesManager::Shutdown();
00066 }
00067
00068 int XMLConfigFile::Count(const string &xpathexpr) const {
00069 XPathResult *result = query(xpathexpr);
00070
00071 assert(result);
00072
00073 return result->getSnapshotLength();
00074 }
00075
00076 namespace {
00077 class DefaultErrorHandler : public ErrorHandler {
00078 public:
00079 virtual void warning(const SAXParseException &e) {
00080 throw XMLConfigFile::ParseErrorException(StrX(e.getMessage()));
00081 }
00082
00083 virtual void error(const SAXParseException &e) {
00084 throw XMLConfigFile::ParseErrorException(StrX(e.getMessage()));
00085 }
00086
00087 virtual void fatalError(const SAXParseException &e) {
00088 throw XMLConfigFile::ParseErrorException(StrX(e.getMessage()));
00089 }
00090
00091 virtual void resetErrors() {}
00092 };
00093 }
00094
00095 void XMLConfigFile::initialize(const string &filename,
00096 const string &schema_filename,
00097 ErrorHandler *error_handler)
00098 {
00099 XercesManager::Initialize();
00100
00101
00102 m_parser = new XercesDOMParser();
00103
00104
00105 if(schema_filename.size() > 0) {
00106 m_parser->setValidationScheme(XercesDOMParser::Val_Always);
00107 m_parser->setDoNamespaces(true);
00108 m_parser->setDoSchema(true);
00109 m_parser->setValidationSchemaFullChecking(true);
00110 m_parser->setExternalNoNamespaceSchemaLocation(schema_filename.c_str());
00111 } else {
00112 m_parser->setValidationScheme(XercesDOMParser::Val_Never);
00113 }
00114
00115
00116 ErrorHandler *default_error_handler = 0;
00117 if(error_handler)
00118 m_parser->setErrorHandler(error_handler);
00119 else {
00120 default_error_handler = new DefaultErrorHandler();
00121 m_parser->setErrorHandler(default_error_handler);
00122 }
00123
00124
00125 try {
00126 m_parser->parse(filename.c_str());
00127 }
00128 catch(const XMLException &e) {
00129 throw ParseErrorException(StrX(e.getMessage()));
00130 }
00131 catch(const DOMException &e) {
00132 throw ParseErrorException(StrX(e.msg));
00133 }
00134
00135
00136 delete default_error_handler;
00137
00138
00139 m_rootelement = m_parser->getDocument()->getDocumentElement();
00140
00141
00142
00143
00144 m_evaluator = XPathEvaluator::createEvaluator();
00145
00146
00147
00148 m_nsresolver = m_evaluator->createNSResolver(m_rootelement);
00149 }
00150
00151 XPathResult *XMLConfigFile::query(const string &xpathexpr) const {
00152
00153
00154
00155 XPathExpression *parsed_expression;
00156 try {
00157 parsed_expression = m_evaluator->createExpression(
00158 XStr(xpathexpr),
00159 m_nsresolver
00160 );
00161 }
00162 catch(const XPathException &e) {
00163 throw QueryErrorException(e.getString());
00164 }
00165
00166
00167
00168
00169 XPathResult *result = 0;
00170
00171 try {
00172 result = parsed_expression->evaluate(
00173 m_rootelement,
00174 XPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
00175 result
00176 );
00177 }
00178 catch(const XPathException &e) {
00179 throw QueryErrorException(e.getString());
00180 }
00181
00182 return result;
00183 }
00184
00185 string XMLConfigFile::get_string(const string &xpathexpr) const {
00186 XPathResult *result = query(xpathexpr);
00187
00188 if(result->getSnapshotLength() != 1)
00189 throw QueryErrorException("Query resulted in zero or multiple answers.");
00190
00191 return StrX(result->snapshotItem(0)->getNodeValue());
00192 }