-
Notifications
You must be signed in to change notification settings - Fork 0
/
parseXML.cpp
118 lines (103 loc) · 3.11 KB
/
parseXML.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <cstring>
#include <sstream>
#include "parseXML.h"
void ParseXML::parseXML() {
parser = XML_ParserCreate(NULL);
if (!parser) {
throw string("Couldn't allocate memory for parser");
}
XML_SetUserData(parser, this);
XML_SetElementHandler(parser, wrapper4Start, wrapper4End);
XML_SetCharacterDataHandler(parser, wrapper4Chars);
std::fstream in;
in.open(filename.c_str(), std::ios::in);
if (!in) {
throw string("Cannot open xml file: ")+filename;
}
int length = 0;
in.getline(buff, BUFSIZE);
while ( true ) {
if (! XML_Parse(parser, buff, strlen(buff), length)) {
std::cout << "Parse error at line "
<< XML_GetCurrentLineNumber(parser)
<< XML_ErrorString(XML_GetErrorCode(parser))
<< std::endl;
throw string("Couldn't parse file: ") + filename;
}
if ( in.eof() ) break;
else in.getline(buff, BUFSIZE);
}
}
void ParseXML::displayData() const {
std::map<string, string>::const_iterator ptr = xmlData.begin();
while ( ptr != xmlData.end() ) {
std::cout << '(' << ptr->first << ", "
<< ptr->second << ')' << std::endl;
++ptr;
}
}
std::string ParseXML::makeTag(const std::string& name) const {
std::string tagName;
for (unsigned int i = 1; i < tagNames.size()-1; ++i) {
tagName += tagNames[i]+'/';
}
tagName += tagNames[ tagNames.size()-1 ];
tagName += std::string("/")+name;
return tagName;
}
std::string ParseXML::makeTag() const {
std::string tagName;
for (unsigned int i = 1; i < tagNames.size()-1; ++i) {
tagName += tagNames[i]+'/';
}
tagName += tagNames[ tagNames.size()-1 ];
return tagName;
}
void ParseXML::start(const char *el, const char *attr[]) {
tagNames.push_back(el);
for (int i = 0; attr[i]; i += 2) {
xmlData.insert(std::make_pair(makeTag(attr[i]), attr[i+1]));
}
}
void ParseXML::end(const char *tagEnd) {
if ( tagEnd != tagNames.back() ) {
throw std::string("Tags ") + tagEnd+" and "+tagNames.back()+
std::string(" don't match");
}
tagNames.pop_back();
}
void ParseXML::stripTrailWhiteSpace(string& str) const {
int length = str.size();
int i = length-1;
while (i >= 0) {
if (str[i] != ' ' && str[i] != '\n' && str[i] != '\t') {
break;
}
else if (str[i] == ' ' || str[i] == '\n' || str[i] == '\t') {
str.erase(i, 1);
}
--i;
}
}
void ParseXML::chars(const char *text, int textlen) {
// The text is not zero terminated; thus we need the length:
string str(text, textlen);
// The text is likely to have trailing white space, e.g. newline, etc
stripTrailWhiteSpace(str);
if ( str.size() ) {
xmlData.insert(std::pair<string,string>(makeTag(), str));
}
}
void ParseXML::
wrapper4Start(void *data, const char *el, const char **attr) {
ParseXML * parser = static_cast<ParseXML*>(data);
parser->start(el, attr);
}
void ParseXML::wrapper4End(void *data, const char *el) {
ParseXML * parser = static_cast<ParseXML*>(data);
parser->end(el);
}
void ParseXML::wrapper4Chars(void *data, const char *text, int textlen) {
ParseXML * parser = static_cast<ParseXML*>(data);
parser->chars(text, textlen);
}