1 This file was updated on Saturday, 2012-10-13 at 3:13 PM
2
3
4 ======================================================================
5 sample.xml
6 ======================================================================
7
8
9
10
17
18
22
23
26
27
28
29
30 ======================================================================
31 parser.hpp
32 ======================================================================
33
34
35 /*
36 * File: parser.hpp
37 * Author: Jesse M. Heines, UMass Lowell CS, heines@cs.uml.edu
38 *
39 * Downloaded on October 13, 2012, 2:55 PM
40 * Source: http://www.yolinux.com/TUTORIALS/XML-Xerces-C.html
41 */
42
43 #ifndef XML_PARSER_HPP
44 #define XML_PARSER_HPP
45 /**
46 * @file
47 * Class "GetConfig" provides the functions to read the XML data.
48 * @version 1.0
49 */
50 #include
51 #include
52 #include
53 #include
54 #include
55 #include
56 #include
57 #include
58 #include
59
60 #include
61 #include
62
63 #include
64 #include
65
66 // Error codes
67
68 enum {
69 ERROR_ARGS = 1,
70 ERROR_XERCES_INIT,
71 ERROR_PARSE,
72 ERROR_EMPTY_DOCUMENT
73 };
74
75 class GetConfig
76 {
77 public:
78 GetConfig();
79 ~GetConfig();
80 void readConfigFile(std::string&) throw(std::runtime_error);
81
82 char *getOptionA() { return m_OptionA; };
83 char *getOptionB() { return m_OptionB; };
84
85 private:
86 xercesc::XercesDOMParser *m_ConfigFileParser;
87 char* m_OptionA;
88 char* m_OptionB;
89
90 // Internal class use only. Hold Xerces data in UTF-16 SMLCh type.
91
92 XMLCh* TAG_root;
93
94 XMLCh* TAG_ApplicationSettings;
95 XMLCh* ATTR_OptionA;
96 XMLCh* ATTR_OptionB;
97 };
98 #endif
99
100
101 ======================================================================
102 parser.cpp
103 ======================================================================
104
105
106 /*
107 * File: parser.cpp
108 * Author: Jesse M. Heines, UMass Lowell CS, heines@cs.uml.edu
109 *
110 * Downloaded on October 13, 2012, 3:03 PM
111 * Source: http://www.yolinux.com/TUTORIALS/XML-Xerces-C.html
112 */
113
114 #include
115 #include
116 #include
117 #include
118 #include
119
120 #include
121 #include
122 #include
123 #include
124
125 #include "parser.hpp"
126
127 using namespace xercesc;
128 using namespace std;
129
130 /**
131 * Constructor initializes xerces-C libraries.
132 * The XML tags and attributes which we seek are defined.
133 * The xerces-C DOM parser infrastructure is initialized.
134 */
135
136 GetConfig::GetConfig()
137 {
138 try
139 {
140 XMLPlatformUtils::Initialize(); // Initialize Xerces infrastructure
141 }
142 catch( XMLException& e )
143 {
144 char* message = XMLString::transcode( e.getMessage() );
145 cerr << "XML toolkit initialization error: " << message << endl;
146 XMLString::release( &message );
147 // throw exception here to return ERROR_XERCES_INIT
148 }
149
150 // Tags and attributes used in XML file.
151 // Can't call transcode till after Xerces Initialize()
152 TAG_root = XMLString::transcode("root");
153 TAG_ApplicationSettings = XMLString::transcode("ApplicationSettings");
154 ATTR_OptionA = XMLString::transcode("option_a");
155 ATTR_OptionB = XMLString::transcode("option_b");
156
157 m_ConfigFileParser = new XercesDOMParser;
158 }
159
160 /**
161 * Class destructor frees memory used to hold the XML tag and
162 * attribute definitions. It als terminates use of the xerces-C
163 * framework.
164 */
165
166 GetConfig::~GetConfig()
167 {
168 // Free memory
169
170 delete m_ConfigFileParser;
171 if(m_OptionA) XMLString::release( &m_OptionA );
172 if(m_OptionB) XMLString::release( &m_OptionB );
173
174 try
175 {
176 XMLString::release( &TAG_root );
177
178 XMLString::release( &TAG_ApplicationSettings );
179 XMLString::release( &ATTR_OptionA );
180 XMLString::release( &ATTR_OptionB );
181 }
182 catch( ... )
183 {
184 cerr << "Unknown exception encountered in TagNamesdtor" << endl;
185 }
186
187 // Terminate Xerces
188
189 try
190 {
191 XMLPlatformUtils::Terminate(); // Terminate after release of memory
192 }
193 catch( xercesc::XMLException& e )
194 {
195 char* message = xercesc::XMLString::transcode( e.getMessage() );
196
197 cerr << "XML ttolkit teardown error: " << message << endl;
198 XMLString::release( &message );
199 }
200 }
201
202 /**
203 * This function:
204 * - Tests the access and availability of the XML configuration file.
205 * - Configures the xerces-c DOM parser.
206 * - Reads and extracts the pertinent information from the XML config file.
207 *
208 * @param in configFile The text string name of the HLA configuration file.
209 */
210
211 void GetConfig::readConfigFile(string& configFile)
212 throw( std::runtime_error )
213 {
214 // Test to see if the file is ok.
215
216 struct stat fileStatus;
217
218 int iretStat = stat(configFile.c_str(), &fileStatus);
219 if( iretStat == ENOENT )
220 throw ( std::runtime_error("Path file_name does not exist, or path is an empty string.") );
221 else if( iretStat == ENOTDIR )
222 throw ( std::runtime_error("A component of the path is not a directory."));
223 else if( iretStat == ELOOP )
224 throw ( std::runtime_error("Too many symbolic links encountered while traversing the path."));
225 else if( iretStat == EACCES )
226 throw ( std::runtime_error("Permission denied."));
227 else if( iretStat == ENAMETOOLONG )
228 throw ( std::runtime_error("File can not be read\n"));
229
230 // Configure DOM parser.
231
232 m_ConfigFileParser->setValidationScheme( XercesDOMParser::Val_Never );
233 m_ConfigFileParser->setDoNamespaces( false );
234 m_ConfigFileParser->setDoSchema( false );
235 m_ConfigFileParser->setLoadExternalDTD( false );
236
237 try
238 {
239 m_ConfigFileParser->parse( configFile.c_str() );
240
241 // no need to free this pointer - owned by the parent parser object
242 DOMDocument* xmlDoc = m_ConfigFileParser->getDocument();
243
244 // Get the top-level element: NAme is "root". No attributes for "root"
245
246 DOMElement* elementRoot = xmlDoc->getDocumentElement();
247 if( !elementRoot ) throw(std::runtime_error( "empty XML document" ));
248
249 // Parse XML file for tags of interest: "ApplicationSettings"
250 // Look one level nested within "root". (child of root)
251
252 DOMNodeList* children = elementRoot->getChildNodes();
253 const XMLSize_t nodeCount = children->getLength();
254
255 // For all nodes, children of "root" in the XML tree.
256
257 for( XMLSize_t xx = 0; xx < nodeCount; ++xx )
258 {
259 DOMNode* currentNode = children->item(xx);
260 if( currentNode->getNodeType() && // true is not NULL
261 currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
262 {
263 // Found node which is an Element. Re-cast node as element
264 DOMElement* currentElement
265 = dynamic_cast< xercesc::DOMElement* >( currentNode );
266 if( XMLString::equals(currentElement->getTagName(), TAG_ApplicationSettings))
267 {
268 // Already tested node as type element and of name "ApplicationSettings".
269 // Read attributes of element "ApplicationSettings".
270 const XMLCh* xmlch_OptionA
271 = currentElement->getAttribute(ATTR_OptionA);
272 m_OptionA = XMLString::transcode(xmlch_OptionA);
273
274 const XMLCh* xmlch_OptionB
275 = currentElement->getAttribute(ATTR_OptionB);
276 m_OptionB = XMLString::transcode(xmlch_OptionB);
277
278 break; // Data found. No need to look at other elements in tree.
279 }
280 }
281 }
282 }
283 catch( xercesc::XMLException& e )
284 {
285 char* message = xercesc::XMLString::transcode( e.getMessage() );
286 ostringstream errBuf;
287 errBuf << "Error parsing file: " << message << flush;
288 XMLString::release( &message );
289 }
290 }
291
292 // the following line was added by JMH to get main to run
293 #define MAIN_TEST
294
295 #ifdef MAIN_TEST
296 /* This main is provided for unit test of the class. */
297
298 int main()
299 {
300 string configFile="sample.xml"; // stat file. Get ambigious segfault otherwise.
301
302 GetConfig appConfig;
303
304 appConfig.readConfigFile(configFile);
305
306 cout << "Application option A=" << appConfig.getOptionA() << endl;
307 cout << "Application option B=" << appConfig.getOptionB() << endl;
308
309 return 0;
310 }
311 #endif
312
314
315 ======================================================================