CGEM BOSS 6.6.5.g
BESIII Offline Software System
Loading...
Searching...
No Matches
XmlParser.cxx
Go to the documentation of this file.
1// $Header: /bes/bes/BossCvs/Calibration/xmlBase/src/XmlParser.cxx,v 1.1.1.1 2005/10/17 06:10:27 maqm Exp $
2// Author: J. Bogart
3
4#include <iostream> // for endl, cerr,...
5#include "xmlBase/XmlParser.h"
6#include "xmlBase/EResolver.h"
7#include "xmlBase/Dom.h"
8#include "facilities/Util.h"
9#include <xercesc/framework/LocalFileInputSource.hpp>
10#include <xercesc/framework/MemBufInputSource.hpp>
11#include <xercesc/util/XMLString.hpp>
12#include <xercesc/framework/XMLValidator.hpp>
13#include <xercesc/util/PlatformUtils.hpp>
14
15namespace {
16 XERCES_CPP_NAMESPACE_USE
17 bool checkDocType(const DOMDocument* doc, const std::string docType) {
18 bool ret = false;
19 const DOMDocumentType* typeDecl = doc->getDoctype();
20 if (typeDecl != 0) {
21 const XMLCh* name = typeDecl->getName();
22 XMLCh* transDocType = XMLString::transcode(docType.c_str());
23 ret = XMLString::equals(name, transDocType);
24 XMLString::release(&transDocType);
25
26 }
27 return ret;
28 }
29}
30
31
32
33namespace xmlBase {
34 XERCES_CPP_NAMESPACE_USE
35 int XmlParser::didInit = 0;
36
37 // class XMLScanner;
38
39 XmlParser::XmlParser(bool throwErrors) : m_throwErrors(throwErrors),
40 m_doSchema(false) {
41 if (!didInit) {
42 try {
43 XMLPlatformUtils::Initialize();
44 }
45 catch(const XMLException& toCatch)
46 { // may want to redirect in Gaudi environment
47 char* charMsg = XMLString::transcode(toCatch.getMessage());
48 std::string msg = std::string(charMsg);
49 XMLString::release(&charMsg);
50
51 std::string errMsg("Error during Xerces-c Initialization: \n");
52 errMsg += " Exception message: ";
53 errMsg += msg;
54 if (m_throwErrors) {
55 throw ParseException(msg);
56 } else {
57 std::cerr << errMsg << std::endl;
58 return;
59 }
60 }
61 didInit = 1;
62 }
63 m_parser = new XercesDOMParser();
64
65 m_errorHandler = new XmlErrorHandler(throwErrors);
66
67 // According to documentation we shouldn't need this, but
68 // just in case..
69 m_parser->setValidationScheme(AbstractDOMParser::Val_Auto);
70 /*
71 m_parser->setDoNamespaces(true);
72 m_parser->setDoSchema(true);
73 m_parser->setValidationSchemaFullChecking(true);
74 */
75
76 m_resolver = new EResolver();
77 m_parser->setXMLEntityResolver(m_resolver);
78 m_parser->setErrorHandler(m_errorHandler);
79
80
81
82 // Don't keep entity reference nodes. We don't use them
83 // and they can cause confusion
84 m_parser->setCreateEntityReferenceNodes(false);
85 // Have to leave this line out for now since it causes weirdness
86 // with DOMDocument::getElementById
87
88 // As long as we don't need to re-serialize, we can forget about
89 // ingnorable white space and save a bit of memory.
90 m_parser->setIncludeIgnorableWhitespace(false);
91 }
92 void XmlParser::doSchema(bool doit) {
93 m_doSchema = doit; // just to keep a record of what we think we're doing
94
95 // m_parser->setValidationScheme(AbstractDOMParser::Val_Always);
96 m_parser->setDoNamespaces(doit);
97 m_parser->setDoSchema(doit);
98 m_parser->setValidationSchemaFullChecking(doit);
99 }
100
102 delete m_errorHandler;
103 delete m_resolver;
104 // delete m_parser; temporary, until we can figure out why there
105 // are sometimes problems while freeing this piece of memory.
106 }
107
108 DOMDocument* XmlParser::parse(const char* const filename,
109 const std::string& docType) {
110 XERCES_CPP_NAMESPACE_USE
111 // Reset from any previous parse
112 m_errorsOccurred = false;
113 m_resolver->clean();
114
115 // translate environment variables, if any
116 std::string fname(filename);
117 int nExpand = facilities::Util::expandEnvVar(&fname);
118 if (nExpand < 0) {
119 std::string errMsg("xmlBase::XmlParser::parse ");
120 errMsg += "Filename arg. contained untranslatable env. variables";
121 if (m_throwErrors) {
122 throw
123 ParseException(errMsg);
124 } else {
125 std::cerr << errMsg << std::endl;
126 return 0;
127 }
128 }
129
130 // parse file
131 try {
132 // XMLCh* filenameXMLCh = Dom::transToXMLCh(filename);
133 XMLCh* filenameXMLCh = XMLString::transcode(fname.c_str());
134 LocalFileInputSource fileSource(filenameXMLCh);
135 m_parser->parse(fileSource);
136 XMLString::release(&filenameXMLCh);
137 }
138 catch (const XMLException& e) {
139 char* charMsg = XMLString::transcode(e.getMessage());
140 std::string msg = std::string(charMsg);
141 XMLString::release(&charMsg);
142 std::string errMsg("xmlBase::XmlParser::parse ");
143 errMsg += "Error occurred while parsing file ";
144 errMsg += fname;
145 m_errorsOccurred = true;
146 m_parser->reset();
147 if (m_throwErrors) {
148 errMsg += " ";
149 errMsg += msg;
150 throw ParseException(errMsg);
151 }
152 else {
153 std::cerr << errMsg << std::endl
154 << "Message: " << msg << std::endl;
155 return 0;
156 }
157
158 }
159
160 if (m_errorHandler->getFatalCount() + m_errorHandler->getErrorCount()) {
161 // Put out message
162 m_parser->reset(); // may be used to parse new input
163 return 0;
164 }
165 if (docType != std::string("")) { // check actual docType matches requested
166 bool ok = checkDocType(m_parser->getDocument(), docType);
167
168 if (ok) return m_parser->getDocument();
169
170 // Either there was no docType at all or it didn't match
171 m_parser->reset();
172 return 0;
173 }
174
175 return m_parser->getDocument();
176 // if ok return document node; else null
177 }
178
179 // this is the string version, very stupidly mostly copied from above.
180 DOMDocument* XmlParser::parse(const std::string& input,
181 const std::string& docType) {
182 XERCES_CPP_NAMESPACE_USE
183
184 // parse file
185 m_errorsOccurred = false;
186 try {
187 char fakeid =99;
188 XMLCh* buffer = XMLString::transcode(input.c_str());
189 // XMLCh* buffer = Dom::transToXMLCh(input.c_str());
190
191 unsigned int byteCount = sizeof(XMLCh) * input.length();
192
193 MemBufInputSource source((const unsigned char*)buffer, byteCount,
194 &fakeid, false);
195 m_parser->parse(source);
196 XMLString::release(&buffer);
197 }
198 catch (const XMLException& e) {
199 char* charMsg = XMLString::transcode(e.getMessage());
200 std::string msg = std::string(charMsg);
201 XMLString::release(&charMsg);
202 m_errorsOccurred = true;
203 m_parser->reset();
204
205 std::string errMsg("xmlBase::XmlParser::parse ");
206 errMsg +=
207 "An error occurred while parsing MemBufInputSource\n Message: ";
208 if (m_throwErrors) {
209 throw ParseException(errMsg);
210 } else {
211 std::cerr << errMsg << std::endl;
212 return 0;
213 }
214 // std::string msg(Dom::transToChar(e.getMessage()));
215 std::cerr <<
216 "An error occurred while parsing MemBufInputSource\n Message: " <<
217 msg << std::endl;
218 return 0;
219 }
220
221 if (m_errorHandler->getFatalCount() + m_errorHandler->getErrorCount()) {
222 // Put out message
223 m_parser->reset(); // may be used to parse new input
224 return 0;
225 }
226
227 if (docType != std::string("")) { // check actual docType matches requested
228 bool ok = checkDocType(m_parser->getDocument(), docType);
229
230 if (ok) return m_parser->getDocument();
231
232 // Either there was no docType at all or it didn't match
233 m_parser->reset();
234 return 0;
235 }
236
237 return m_parser->getDocument();
238 // if ok return document node; else null
239
240
241 }
242
243} // end namespace
static int expandEnvVar(std::string *toExpand, const std::string &openDel=std::string("$("), const std::string &closeDel=std::string(")"))
Exception class for XmlParser, XmlErrorHandler.
DOMDocument * parse(const char *const filename, const std::string &docType=std::string(""))
Parse an xml file, returning document node if successful.
Definition: XmlParser.cxx:108
void doSchema(bool doit)
Call this method to turn on schema processing (else it's off)
Definition: XmlParser.cxx:92
XmlParser(bool throwErrors=false)
Definition: XmlParser.cxx:39