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