22 size_t spaceLoc = tagstr.find(
" ");
23 size_t closeLoc = tagstr.find(
'>');
24 size_t slashLoc = string::npos;
28 slashLoc = tagstr.find(
"/");
31 int endChar = tagstr.size();
32 if (spaceLoc != string::npos)
36 if (closeLoc < endChar && closeLoc != string::npos)
40 if (slashLoc < endChar && slashLoc != string::npos)
48 tagName = tagstr.substr(2, endChar);
53 tagName = tagstr.substr(1, endChar);
60 int isCommentStart = 0;
61 std::streampos curLoc = stream_->tellg();
62 if ((length - position) > 4)
65 stream_->read(buf, 4);
66 if (strncmp(buf,
"<!--", 4) == 0)
71 stream_->seekg(curLoc);
72 return isCommentStart;
78 std::streampos curLoc = stream_->tellg();
79 if ((length - position) > 3)
82 stream_->read(buf, 3);
83 if (strncmp(buf,
"-->", 3) == 0)
88 stream_->seekg(curLoc);
95 std::streampos curLoc = stream_->tellg();
97 stream_->seekg(before.
endLoc);
103 while (foundPOD == 0 && position < length)
113 if (endComment(position, length) == 1)
116 stream_->seekg(3, std::ios_base::cur);
124 if (endComment(position, length) == 1)
127 stream_->seekg(4, std::ios_base::cur);
141 stream_->seekg(curLoc);
148 std::streampos start;
154 int isProcessingInstruction = 0;
156 int isClosingTag = 0;
157 int isSelfClosing = 0;
159 int openCaretFound = 0;
160 int closeCaretFound = 0;
162 int numSingleQuotes = 0;
163 int numDoubleQuotes = 0;
164 while ((current = stream_->get()) && current != EOF && closeCaretFound == 0)
172 start = stream_->tellg();
176 int one = stream_->get();
177 int two = stream_->get();
178 int three = stream_->get();
181 isProcessingInstruction = 1;
183 if (one ==
'!' && two ==
'-' && three ==
'-')
195 if (openCaretFound == 1)
201 else if (current ==
'\"')
205 else if (current ==
'>')
208 if (numSingleQuotes % 2 == 0 && numDoubleQuotes % 2 == 0)
215 if (prev ==
'-' && twoprev ==
'-')
218 end = stream_->tellg();
224 end = stream_->tellg();
245 if (isProcessingInstruction == 0 && isComment == 0)
251 if (isSelfClosing == 1)
255 else if (isClosingTag == 1)
264 elem.
name = getTagName(getTag(elem), elem.
type);
265 elements.push_back(elem);
268 if (isProcessingInstruction == 1 || isComment == 1)
279 std::streampos curLoc = stream_->tellg();
281 std::string result(end - start,
'\0');
282 stream_->seekg(start);
283 stream_->read(result.data(), end - start);
286 stream_->seekg(curLoc);
292 int index = start + 1;
295 while (index < elements.size() && level > 0)
297 const tagType tt = elements[index].type;
302 childIndices.push_back(index);
314 childIndices.push_back(index);
335 for (
int i = 0; i < elements.size(); i++)
337 std::cout << i <<
" ";
341 std::cout <<
"opening, name = " << elements[i].name << std::endl;
345 std::cout <<
"closing, name = " << elements[i].name << std::endl;
349 std::cout <<
"selfClosing, name = " << elements[i].name << std::endl;
353 std::cout <<
"POD" << std::endl;
364 std::vector<XmlElement> tags;
368 for (
int i = 1; i < tags.size(); i++)
374 podElem.
startLoc = tags[i - 1].endLoc;
375 podElem.
endLoc = tags[i].startLoc;
390 cerr <<
"requested a tag index past the end of the vector" << endl;
400 std::streampos curLoc =
stream_->tellg();
410 std::stringstream ss;
411 int commentStart = -1;
415 while (
s.find(
"<!--", commentEnd) != string::npos)
417 commentStart =
s.find(
"<!--", commentEnd);
418 ss <<
s.substr(commentEnd, commentStart - commentEnd);
419 commentEnd =
s.find(
"-->", commentStart);
422 if (commentStart == -1)
429 ss <<
s.substr(commentEnd + 3,
s.size() - commentEnd - 3);
443 for (
int i = 0; i <
children_.size(); i++)
450 if (strict != 0 && index < 0)
452 cerr <<
"In XmlNode with name: " <<
name_ <<
", could not find index for child with name: " << childName << endl;
466 cerr <<
"Asked to get child node: " << i <<
", but there are only " <<
getNumChildren() <<
"nodes" << endl;
476 cerr <<
"Asked to get child node: " << i <<
", but there are only " <<
getNumChildren() <<
"nodes" << endl;
492 if (strict != 0 && index < 0)
494 cerr <<
"In XmlNode with name: " <<
name_ <<
", could not find index for attribute with name: " << attrName << endl;
506 cerr <<
"in XmlNode with name: " <<
name_ <<
", requested attribute with index " << index
507 <<
", but this index is not present." << endl;
557 size_t first = str.find_first_not_of(
" \n\t\v\f\r");
558 if (string::npos == first)
562 size_t last = str.find_last_not_of(
" \n\t\v\f\r");
563 return str.substr(first, (last - first + 1));
570 string tagstr = xs.
getTag(elem);
581 string decliningstring = tagstr.substr(tagstr.find(
name_) +
name_.size() + 1);
589 decliningstring = decliningstring.substr(0, decliningstring.size() - numToRemove);
592 while (decliningstring.size() > 1)
604 key = contentstr.substr(0, breakone);
607 contentstr = contentstr.substr(breakone + 1);
610 if (firstquote == string::npos)
614 contentstr = contentstr.substr(firstquote + 1);
616 if (secondquote == string::npos)
620 val = contentstr.substr(0, secondquote);
623 contentstr = contentstr.substr(secondquote + 1);
628 size_t index = string::npos;
635 for (
int i = 1; i < str.size(); i++)
637 if (str[i] == c && str[i - 1] !=
'\\')
649 std::stringstream ss;
650 for (
int i = 0; i < is; i++)
689 for (
int i = 0; i <
children_.size(); i++)
691 ss <<
children_[i].getString(indentLevel + 2);
714 XmlNode::XmlNode(istream* _stream,
int start,
bool deferValue) : stream_(_stream)
745 vector<int> childIndices;
750 if (childIndices.size() == 0)
773 for (
int i = 0; i < childIndices.size(); i++)
void getNextKeyVal(std::string &contentstr, std::string &key, std::string &val) const
void handleTagString(const XmlStream &xs, int loc)
int startComment(long position, long length) const
int checkForPOD(const XmlElement &before, const XmlElement &after) const
std::vector< attrpair > attributes_
std::vector< XmlElement > elements
int getChildIndex(const std::string &name, int strict=0) const
size_t getPosNextLiveChar(const std::string &str, char c) const
std::string trimWhitespace(const std::string &str) const
std::string getName() const
std::string getValue() const
std::string getInStr(int is) const
std::pair< std::string, std::string > attrpair
std::vector< XmlNode > children_
void write(std::ostream &os, int indentLevel=0) const
void createFromStream(const XmlStream &stream, int start=0, bool deferValue=true)
void findChildElements(int start, std::vector< int > &childIndices, int &podIndex) const
XmlNode & getChild(const std::string &name)
std::string getTagName(const std::string &tag, tagType type) const
std::string getStreamSection(const std::streampos &start, const std::streampos &end) const
int endComment(long position, long length) const
std::string getTag(const XmlElement &e) const
std::string getString(int indentLevel=0) const
int getNumChildren() const
int getAttributeIndex(const std::string &name, int strict=0) const
std::string getAttributeName(int index) const
void getAttribute(const std::string &name, T &result) const
void readToString(std::string &s) const
XmlStream(std::istream *is)