173 static const string sCommentEnd;
174 static const string sCdataStart;
175 static const string sCdataEnd;
176 static const string sDtdStart;
177 static const string sDtdEnd;
178 static const string sDeclarationStart;
179 static const string sDeclarationEnd;
180 static const string sEmptyTagWithAttributes;
181 static const string sEmptyTag;
183 const parsing_bits<char>::character_map parsing_bits<char>::sNameDelimeter = std::string(
"<>/=\"\'");
184 const parsing_bits<char>::character_map parsing_bits<char>::sNameBadDelimeter = std::string(
"<=\"\'");
185 const parsing_bits<char>::character_map parsing_bits<char>::sAttributeValueDelimeter = std::string(
"\"\'");
186 const parsing_bits<char>::character_map parsing_bits<char>::sAttributeValueInvalidOne = std::string(
"<>\"");
187 const parsing_bits<char>::character_map parsing_bits<char>::sAttributeValueInvalidTwo = std::string(
"<>\'");
188 const parsing_bits<char>::character_map parsing_bits<char>::sTagDelimeter = std::string(
"<>");
189 const parsing_bits<char>::character_map parsing_bits<char>::sWhitespace = std::string(
" \t\r\n");
190 const parsing_bits<char>::string parsing_bits<char>::sCommentStart =
"!--";
191 const parsing_bits<char>::string parsing_bits<char>::sCommentEnd =
"-->";
192 const parsing_bits<char>::string parsing_bits<char>::sCdataStart =
"![CDATA[";
193 const parsing_bits<char>::string parsing_bits<char>::sCdataEnd =
"]]>";
194 const parsing_bits<char>::string parsing_bits<char>::sDtdStart =
"!DOCTYPE";
195 const parsing_bits<char>::string parsing_bits<char>::sDtdEnd =
">";
196 const parsing_bits<char>::string parsing_bits<char>::sDeclarationStart =
"?";
197 const parsing_bits<char>::string parsing_bits<char>::sDeclarationEnd =
"?>";
198 const parsing_bits<char>::string parsing_bits<char>::sEmptyTagWithAttributes =
" />";
199 const parsing_bits<char>::string parsing_bits<char>::sEmptyTag =
"/>";
201 struct parsing_bits<wchar_t>
203 typedef std::wstring
string;
205 static const character_map sNameDelimeter;
206 static const character_map sNameBadDelimeter;
207 static const character_map sAttributeValueDelimeter;
208 static const character_map sAttributeValueInvalidOne;
209 static const character_map sAttributeValueInvalidTwo;
210 static const character_map sTagDelimeter;
211 static const character_map sWhitespace;
212 static const string sCommentStart;
213 static const string sCommentEnd;
214 static const string sCdataStart;
215 static const string sCdataEnd;
216 static const string sDtdStart;
217 static const string sDtdEnd;
218 static const string sDeclarationStart;
219 static const string sDeclarationEnd;
220 static const string sEmptyTagWithAttributes;
221 static const string sEmptyTag;
223 const parsing_bits<wchar_t>::character_map parsing_bits<wchar_t>::sNameDelimeter = std::wstring(L
"<>/=\"\'");
224 const parsing_bits<wchar_t>::character_map parsing_bits<wchar_t>::sNameBadDelimeter = std::wstring(L
"<=\"\'");
225 const parsing_bits<wchar_t>::character_map parsing_bits<wchar_t>::sAttributeValueDelimeter = std::wstring(L
"\"\'");
226 const parsing_bits<wchar_t>::character_map parsing_bits<wchar_t>::sAttributeValueInvalidOne = std::wstring(L
"<>\"");
227 const parsing_bits<wchar_t>::character_map parsing_bits<wchar_t>::sAttributeValueInvalidTwo = std::wstring(L
"<>\'");
228 const parsing_bits<wchar_t>::character_map parsing_bits<wchar_t>::sTagDelimeter = std::wstring(L
"<>");
229 const parsing_bits<wchar_t>::character_map parsing_bits<wchar_t>::sWhitespace = std::wstring(L
" \t\r\n");
230 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sCommentStart = L
"!--";
231 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sCommentEnd = L
"-->";
232 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sCdataStart = L
"![CDATA[";
233 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sCdataEnd = L
"]]>";
234 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sDtdStart = L
"!DOCTYPE";
235 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sDtdEnd = L
">";
236 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sDeclarationStart = L
"?";
237 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sDeclarationEnd = L
"?>";
238 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sEmptyTagWithAttributes = L
" />";
239 const parsing_bits<wchar_t>::string parsing_bits<wchar_t>::sEmptyTag = L
"/>";
242 template <
typename CharT,
typename Alloc>
243 const basic_character_map<CharT> basic_xml<CharT, Alloc>::sNameDelimeter = parsing_bits<CharT>::sNameDelimeter;
244 template <
typename CharT,
typename Alloc>
245 const basic_character_map<CharT> basic_xml<CharT, Alloc>::sNameBadDelimeter = parsing_bits<CharT>::sNameBadDelimeter;
246 template <
typename CharT,
typename Alloc>
247 const basic_character_map<CharT> basic_xml<CharT, Alloc>::sAttributeValueDelimeter = parsing_bits<CharT>::sAttributeValueDelimeter;
248 template <
typename CharT,
typename Alloc>
249 const basic_character_map<CharT> basic_xml<CharT, Alloc>::sAttributeValueInvalidOne = parsing_bits<CharT>::sAttributeValueInvalidOne;
250 template <
typename CharT,
typename Alloc>
251 const basic_character_map<CharT> basic_xml<CharT, Alloc>::sAttributeValueInvalidTwo = parsing_bits<CharT>::sAttributeValueInvalidTwo;
252 template <
typename CharT,
typename Alloc>
253 const basic_character_map<CharT> basic_xml<CharT, Alloc>::sTagDelimeter = parsing_bits<CharT>::sTagDelimeter;
254 template <
typename CharT,
typename Alloc>
255 const basic_character_map<CharT> basic_xml<CharT, Alloc>::sWhitespace = parsing_bits<CharT>::sWhitespace;
256 template <
typename CharT,
typename Alloc>
258 template <
typename CharT,
typename Alloc>
260 template <
typename CharT,
typename Alloc>
262 template <
typename CharT,
typename Alloc>
264 template <
typename CharT,
typename Alloc>
266 template <
typename CharT,
typename Alloc>
268 template <
typename CharT,
typename Alloc>
270 template <
typename CharT,
typename Alloc>
272 template <
typename CharT,
typename Alloc>
274 template <
typename CharT,
typename Alloc>
277 template <
typename CharT,
typename Alloc>
280 for (
typename node_list::const_iterator i = iContent.begin(); i != iContent.end(); ++i)
281 if ((**i).type() & aFilter)
286 template <
typename CharT,
typename Alloc>
292 template <
typename CharT,
typename Alloc>
295 for (
typename node_list::iterator i = iContent.begin(); i != iContent.end(); ++i)
296 if ((**i).type() & aFilter)
301 template <
typename CharT,
typename Alloc>
304 return iterator(*
this, iContent.end(), aFilter);
307 template <
typename CharT,
typename Alloc>
310 for (
typename node::const_iterator i = begin(); i != end(); ++i)
316 template <
typename CharT,
typename Alloc>
319 auto result = find(aName);
326 template <
typename CharT,
typename Alloc>
329 for (
typename node::iterator i = begin(); i != end(); ++i)
335 template <
typename CharT,
typename Alloc>
338 auto result = find(aName);
345 template <
typename CharT,
typename Alloc>
348 for (
typename node::iterator i = begin(); i != end(); ++i)
352 typename node::iterator newNode = end();
356 template <
typename CharT,
typename Alloc>
357 template <
typename Exception>
360 typename node::const_iterator i = find(aName);
366 template <
typename CharT,
typename Alloc>
367 template <
typename Exception>
370 typename node::iterator i = find(aName);
376 template <
typename CharT,
typename Alloc>
379 return iAttributes.find(aAttributeName) != iAttributes.end();
382 template <
typename CharT,
typename Alloc>
385 typename attribute_list::const_iterator a = iAttributes.find(aAttributeName);
386 if (a != iAttributes.end())
388 static const string null;
392 template <
typename CharT,
typename Alloc>
395 if (has_attribute(aNewAttributeName))
396 return attribute_value(aNewAttributeName);
398 return attribute_value(aOldAttributeName);
401 template <
typename CharT,
typename Alloc>
406 if (i->type() == node::Text)
411 template <
typename CharT,
typename Alloc>
414 iAttributes[aAttributeName] = aAttributeValue;
417 template <
typename CharT,
typename Alloc>
423 template <
typename CharT,
typename Alloc>
424 template <
typename T>
427 if (!iLastWasNewLine)
429 iLastWasNewLine =
false;
432 template <
typename CharT,
typename Alloc>
433 typename basic_xml<CharT, Alloc>::node_writer& basic_xml<CharT, Alloc>::node_writer::operator<<(
const string& aData)
435 iStream << aData.to_std_string_view();
436 if (aData.size() && aData[aData.size() - 1] == characters<CharT>::sNewLineChar)
437 iLastWasNewLine =
true;
439 iLastWasNewLine =
false;
443 template <
typename CharT,
typename Alloc>
445 endl(
std::endl), iError(false), iIndentChar(characters<CharT>::sTabChar), iIndentCount(1), iStripWhitespace(aStripWhitespace)
447 for (std::size_t entityIndex = 0; entityIndex < predefined_entities<CharT>::PredefinedEntityCount; ++entityIndex)
448 iEntities.push_back(predefined_entities<CharT>::sPredefinedEntities[entityIndex]);
451 template <
typename CharT,
typename Alloc>
453 endl(
std::endl), iError(false), iIndentChar(characters<CharT>::sTabChar), iIndentCount(1), iStripWhitespace(aStripWhitespace)
455 for (std::size_t entityIndex = 0; entityIndex < predefined_entities<CharT>::PredefinedEntityCount; ++entityIndex)
456 iEntities.push_back(predefined_entities<CharT>::sPredefinedEntities[entityIndex]);
457 std::ifstream input(aPath);
463 template <
typename CharT,
typename Alloc>
467 iDocumentText.clear();
471 template <
typename CharT,
typename Alloc>
477 template <
typename CharT,
typename Alloc>
483 template <
typename CharT,
typename Alloc>
486 for (
typename node::const_iterator i = iDocument.begin(); i != iDocument.end(); ++i)
487 if (i->type() == node::Element)
488 return static_cast<const element&
>(*i);
493 template <
typename CharT,
typename Alloc>
496 for (
typename node::iterator i = iDocument.begin(); i != iDocument.end(); ++i)
497 if (i->type() == node::Element)
498 return static_cast<element&
>(*i);
499 iDocument.push_back(
new element());
500 return static_cast<element&
>(iDocument.back());
503 template <
typename CharT,
typename Alloc>
506 for (
typename node::const_iterator i = iDocument.begin(); i != iDocument.end(); ++i)
507 if (i->type() == node::Element)
512 template <
typename CharT,
typename Alloc>
516 nextTag.first = std::find(aNext, aDocumentEnd, CharT(characters<CharT>::sElementTagStart));
517 if (nextTag.first != aDocumentEnd)
519 nextTag.second = std::find(nextTag.first, aDocumentEnd, CharT(characters<CharT>::sElementTagEnd));
520 if (
static_cast<typename
string::size_type>(nextTag.second - nextTag.first) >= sCommentStart.size() && std::equal(nextTag.first, nextTag.first+sCommentStart.size(), sCommentStart.begin()))
522 nextTag.iType = node::Comment;
523 nextTag.first += sCommentStart.size();
524 nextTag.second = std::search(nextTag.first, aDocumentEnd, sCommentEnd.begin(), sCommentEnd.end());
525 if (nextTag.second == aDocumentEnd)
526 nextTag.first = aDocumentEnd;
528 else if (
static_cast<typename
string::size_type>(nextTag.second - nextTag.first) >= sDeclarationStart.size() && std::equal(nextTag.first, nextTag.first+sDeclarationStart.size(), sDeclarationStart.begin()))
530 nextTag.iType = node::Declaration;
531 nextTag.first += sDeclarationStart.size();
532 nextTag.second = std::search(nextTag.first, aDocumentEnd, sDeclarationEnd.begin(), sDeclarationEnd.end());
533 if (nextTag.second == aDocumentEnd)
534 nextTag.first = aDocumentEnd;
536 else if (
static_cast<typename
string::size_type>(nextTag.second - nextTag.first) >= sCdataStart.size() && std::equal(nextTag.first, nextTag.first+sCdataStart.size(), sCdataStart.begin()))
538 nextTag.iType = node::Cdata;
539 nextTag.first += sCdataStart.size();
540 nextTag.second = std::search(nextTag.first, aDocumentEnd, sCdataEnd.begin(), sCdataEnd.end());
541 if (nextTag.second == aDocumentEnd)
542 nextTag.first = aDocumentEnd;
544 else if (
static_cast<typename
string::size_type>(nextTag.second - nextTag.first) >= sDtdStart.size() + 1 && std::equal(nextTag.first, nextTag.first+sDtdStart.size(), sDtdStart.begin()) &&
545 sWhitespace.find(*(nextTag.first + sDtdStart.size())))
547 nextTag.iType = node::Dtd;
548 nextTag.first += sDtdStart.size();
549 nextTag.second = nextTag.first;
550 std::size_t nest = 1;
551 while(nextTag.second != aDocumentEnd)
553 if (*nextTag.second == characters<CharT>::sLessThanChar)
555 if (*nextTag.second == characters<CharT>::sGreaterThanChar)
561 if (nextTag.second == aDocumentEnd)
562 nextTag.first = aDocumentEnd;
567 template <
typename CharT,
typename Alloc>
568 typename basic_xml<CharT, Alloc>::string::view_const_iterator basic_xml<CharT, Alloc>::parse(node& aNode,
const tag& aStartTag,
typename basic_xml<CharT, Alloc>::string::view_const_iterator aDocumentEnd)
570 if (aStartTag.first == aDocumentEnd || aStartTag.first >= aStartTag.second)
573 switch(aStartTag.type())
577 if (aNode.type() == node::Document && got_root())
582 element& theElement = aNode.type() == node::Element ?
static_cast<element&
>(aNode) : root();
585 token elementName = next_token(sNameDelimeter,
false, aStartTag.first, aStartTag.second);
586 if (elementName.first == aStartTag.second)
591 theElement.name() = string(elementName.first, elementName.second);
593 typename string::view_const_iterator
next = elementName.second;
596 while(next != aStartTag.second)
598 token attributeName = next_token(sNameDelimeter,
false, next, aStartTag.second);
599 if (attributeName.first == attributeName.second)
601 if (attributeName.first != aStartTag.second &&
602 sNameBadDelimeter.find(*attributeName.first))
607 next = aStartTag.second;
610 token attributeEquals = next_token(sAttributeValueDelimeter,
false, attributeName.second, aStartTag.second);
611 if (attributeEquals.second - attributeEquals.first != 1 || *attributeEquals.first != characters<CharT>::sEqualsChar)
616 token attributeStart = next_token(sAttributeValueDelimeter,
false, attributeEquals.second, aStartTag.second);
617 if (attributeStart.first != attributeStart.second ||
618 attributeStart.first == aStartTag.second ||
619 !sAttributeValueDelimeter.find(*attributeStart.first))
624 token attributeValue = next_token(*attributeStart.first == characters<CharT>::sQuoteChar ? sAttributeValueInvalidOne : sAttributeValueInvalidTwo, true, attributeStart.second + 1, aStartTag.second);
625 if (attributeValue.first == aStartTag.second ||
626 attributeValue.second == aStartTag.second ||
627 !sAttributeValueDelimeter.find(*attributeValue.second))
632 next = attributeValue.second + 1;
633 typename attribute_list::iterator a = theElement.attributes().insert(std::make_pair(
string(attributeName.first, attributeName.second), attributeValue.iHasEntities ? parse_entities(
string(attributeValue.first, attributeValue.second)) : string(attributeValue.first, attributeValue.second))).first;
637 if (*(aStartTag.second-1) == characters<CharT>::sForwardSlashChar)
643 while(next != aDocumentEnd)
645 token contentToken = next_token(sTagDelimeter,
true, next, aDocumentEnd);
646 next = contentToken.second;
647 if (next == aDocumentEnd)
649 string content(contentToken.first, contentToken.second);
651 bool hasContent =
false;
652 for (
typename string::view_const_iterator i = content.cbegin(); !hasContent && i != content.cend(); ++i)
656 case characters<CharT>::sTabChar:
657 case characters<CharT>::sSpaceChar:
658 case characters<CharT>::sNewLineChar:
659 case characters<CharT>::sCarriageReturnChar:
667 if (!content.empty())
669 if (contentToken.iHasEntities)
670 content = parse_entities(content);
671 theElement.push_back(
new text(content));
673 tag nextTag = next_tag(next, aDocumentEnd);
674 if (nextTag.first > nextTag.second)
676 if (nextTag.first == nextTag.second)
681 switch (nextTag.type())
684 if (*nextTag.first == characters<CharT>::sForwardSlashChar)
686 if (theElement.name() !=
string(nextTag.first+1, nextTag.second))
691 theElement.set_use_empty_element_tag(
false);
692 return nextTag.second+1;
694 theElement.push_back(
new element());
697 theElement.push_back(
new comment());
699 case node::Declaration:
700 theElement.push_back(
new declaration());
703 theElement.push_back(
new cdata());
706 theElement.push_back(
new dtd());
711 next = parse(theElement.back(), nextTag, aDocumentEnd);
717 if (aNode.type() == node::Comment)
718 static_cast<comment&
>(aNode).content() = string(aStartTag.first, aStartTag.second);
720 aNode.push_back(
new comment(
string(aStartTag.first, aStartTag.second)));
721 return aStartTag.second + aStartTag.end_skip();
722 case node::Declaration:
723 if (aNode.type() == node::Declaration)
724 static_cast<declaration&
>(aNode).content() = string(aStartTag.first, aStartTag.second);
726 aNode.push_back(
new declaration(
string(aStartTag.first, aStartTag.second)));
727 return aStartTag.second + aStartTag.end_skip();
729 if (aNode.type() == node::Cdata)
730 static_cast<cdata&
>(aNode).content() = string(aStartTag.first, aStartTag.second);
732 aNode.push_back(
new cdata(
string(aStartTag.first, aStartTag.second)));
733 return aStartTag.second + aStartTag.end_skip();
735 if (aNode.type() == node::Dtd)
736 static_cast<dtd&
>(aNode).content() = string(aStartTag.first, aStartTag.second);
738 aNode.push_back(
new dtd(
string(aStartTag.first, aStartTag.second)));
739 return aStartTag.second + aStartTag.end_skip();
746 template <
typename CharT,
typename Alloc>
756 typename std::basic_istream<CharT>::pos_type count = 0;
757 aStream.seekg(0, std::ios::end);
760 count =
static_cast<long>(aStream.tellg());
761 if (count ==
typename std::basic_istream<CharT>::pos_type(-1))
763 aStream.seekg(0, std::ios::beg);
768 string& document = iDocumentText;
770 if (count !=
typename std::basic_istream<CharT>::pos_type(0))
773 aStream.read(&document[0], count);
780 while(aStream.read(buffer, 1024))
781 document.append(buffer,
static_cast<typename
string::size_type>(aStream.gcount()));
783 document.append(buffer,
static_cast<typename
string::size_type>(aStream.gcount()));
786 tag nextTag = next_tag(document.cbegin(), document.cend());
787 while (nextTag.first != document.cend())
789 while(nextTag.first != document.cend() && nextTag.first == nextTag.second)
790 nextTag = next_tag(nextTag.first, document.cend());
791 nextTag = next_tag(parse(iDocument, nextTag, document.cend()), document.cend());
797 template <
typename CharT,
typename Alloc>
801 std::ostringstream buffer;
802 node_writer theWriter(buffer);
803 write_node(theWriter, iDocument, 0);
804 aStream.write(buffer.str().c_str(), buffer.str().length());
808 template <
typename CharT,
typename Alloc>
811 iIndentChar = aIndentChar;
812 iIndentCount = aIndentCount;
815 template <
typename CharT,
typename Alloc>
818 iStripWhitespace = aStripWhitespace;
821 template <
typename CharT,
typename Alloc>
827 for (
typename node::const_iterator i = aNode.begin(); i != aNode.end(); ++i)
829 write_node(aStream, *i, aIndent);
835 const element& theElement =
static_cast<const element&
>(aNode);
837 if (&theElement != &root())
839 aStream << string(aIndent*iIndentCount, iIndentChar);
840 aStream << characters<CharT>::sLessThanChar;
841 aStream << theElement.name();
843 if (!theElement.attributes().empty())
844 for (
typename attribute_list::const_iterator i = theElement.attributes().begin(); i != theElement.attributes().end(); ++i)
845 aStream << characters<CharT>::sSpaceChar << i->first << characters<CharT>::sEqualsChar << characters<CharT>::sQuoteChar << generate_entities(i->second) << characters<CharT>::sQuoteChar;
849 aStream << characters<CharT>::sGreaterThanChar;
850 for (
typename node::const_iterator i = aNode.begin(); i != aNode.end(); ++i)
855 if (i != aNode.begin())
857 if (iStripWhitespace)
860 aStream << string((aIndent+1)*iIndentCount, iIndentChar);
865 case node::Declaration:
867 aStream << string((aIndent+1)*iIndentCount, iIndentChar);
876 write_node(aStream, *i, aIndent+1);
878 if (aNode.back().type() != node::Text)
879 aStream <<
endl << string(aIndent*iIndentCount, iIndentChar);
880 aStream << characters<CharT>::sLessThanChar << characters<CharT>::sForwardSlashChar << theElement.name() << characters<CharT>::sGreaterThanChar;
882 else if (theElement.use_empty_element_tag())
883 aStream << (theElement.attributes().size() ? sEmptyTagWithAttributes : sEmptyTag);
885 aStream << characters<CharT>::sGreaterThanChar << characters<CharT>::sLessThanChar << characters<CharT>::sForwardSlashChar << theElement.name() << characters<CharT>::sGreaterThanChar;
889 aStream << generate_entities(static_cast<const text&>(aNode).content());
892 aStream << characters<CharT>::sLessThanChar << sCommentStart << static_cast<const comment&>(aNode).content() << sCommentEnd;
894 case node::Declaration:
895 aStream << characters<CharT>::sLessThanChar << sDeclarationStart << static_cast<const declaration&>(aNode).content() << sDeclarationEnd;
898 aStream << characters<CharT>::sLessThanChar << sCdataStart << static_cast<const cdata&>(aNode).content() << sCdataEnd;
901 aStream << characters<CharT>::sLessThanChar << sDtdStart << static_cast<const dtd&>(aNode).content() << sDtdEnd;
908 template <
typename CharT,
typename Alloc>
914 template <
typename CharT,
typename Alloc>
920 template <
typename CharT,
typename Alloc>
923 aParent.
erase(aPosition);
926 template <
typename CharT,
typename Alloc>
929 return aParent.
find(aName);
932 template <
typename CharT,
typename Alloc>
935 return aParent.
find(aName);
938 template <
typename CharT,
typename Alloc>
944 template <
typename CharT,
typename Alloc>
947 string newString = aString;
949 while((pos = newString.find(characters<CharT>::sAmpersandChar, pos)) != string::npos)
951 typename string::size_type endPos = newString.find(characters<CharT>::sSemicolonChar, pos);
952 if (endPos == string::npos || (pos+1 == endPos))
957 bool replaced =
false;
958 if (
const_cast<const string&
>(newString)[pos+1] == characters<CharT>::sHashChar)
960 string characterValue = newString.substr(pos+2, endPos - (pos + 2));
966 return strtol(aString.c_str(), 0, aBase);
970 return wcstol(aString.c_str(), 0, aBase);
973 if (characterValue[0] != characters<CharT>::sHexChar)
974 character +=
static_cast<CharT
>(converter::string_to_integer(characterValue, 10));
977 characterValue.erase(0, 1);
978 character +=
static_cast<CharT
>(converter::string_to_integer(characterValue, 16));
980 newString.replace(pos, (endPos - pos) + 1, character);
986 for(
typename entity_list::const_iterator i = iEntities.begin(); i != iEntities.end(); ++i)
989 placeholder += characters<CharT>::sAmpersandChar;
990 placeholder += i->first;
991 placeholder += characters<CharT>::sSemicolonChar;
992 if (placeholder.size() != endPos - pos + 1)
994 if (std::equal(placeholder.cbegin(), placeholder.cend(), newString.
cbegin() + pos))
996 newString.replace(pos, placeholder.size(), i->second);
997 pos += i->second.
size();
1004 newString.
erase(pos, (endPos - pos) + 1);
1009 template <
typename CharT,
typename Alloc>
1012 string newString = aString;
1013 for(
typename entity_list::const_iterator i = iEntities.begin(); i != iEntities.end(); ++i)
1016 placeholder += characters<CharT>::sAmpersandChar;
1017 placeholder += i->first;
1018 placeholder += characters<CharT>::sSemicolonChar;
1020 while((pos = newString.find(i->second, pos)) != string::npos)
1022 newString.replace(pos, i->second.size(), placeholder);
1023 pos += placeholder.
size();
1029 template <
typename CharT,
typename Alloc>
1030 void basic_xml<CharT, Alloc>::strip(
string& aString)
const
1033 bool foundPrintable =
false;
1034 while (!foundPrintable && start < aString.size())
1036 switch(aString[start])
1038 case characters<CharT>::sTabChar:
1039 case characters<CharT>::sSpaceChar:
1040 case characters<CharT>::sNewLineChar:
1041 case characters<CharT>::sCarriageReturnChar:
1045 foundPrintable =
true;
1052 aString.erase(0, start);
1056 if (aString.empty())
1059 foundPrintable =
false;
1060 while (!foundPrintable && end != string::npos)
1062 switch(aString[end])
1064 case characters<CharT>::sTabChar:
1065 case characters<CharT>::sSpaceChar:
1066 case characters<CharT>::sNewLineChar:
1067 case characters<CharT>::sCarriageReturnChar:
1074 foundPrintable =
true;
1078 if (end != string::npos)
1079 aString.erase(end+1, aString.size() - (end+1));
1083 while(src != aString.end())
1085 CharT srcChar = *src++;
1088 case characters<CharT>::sTabChar:
1089 case characters<CharT>::sSpaceChar:
1090 case characters<CharT>::sNewLineChar:
1091 case characters<CharT>::sCarriageReturnChar:
1092 if (dest != aString.begin() && *(dest-1) != characters<CharT>::sSpaceChar)
1093 *dest++ = characters<CharT>::sSpaceChar;
1098 src =
static_cast<string&
>(aString).begin();
1099 dest =
static_cast<string&
>(aString).begin();
1107 if (found && dest != aString.end())
1108 aString.erase(dest, aString.end());
1111 template <
typename CharT,
typename Alloc>
1112 void basic_xml<CharT, Alloc>::strip_if(
string& aString)
const
1114 if (iStripWhitespace)
1118 template <
typename CharT,
typename Alloc>
1119 typename basic_xml<CharT, Alloc>::token basic_xml<CharT, Alloc>::next_token(
const basic_character_map<CharT>& aDelimeters,
bool aIgnoreWhitespace,
typename basic_xml<CharT, Alloc>::string::view_const_iterator aCurrent,
typename basic_xml<CharT, Alloc>::string::view_const_iterator aEnd)
const
1121 if (!aIgnoreWhitespace)
1123 while (aCurrent != aEnd)
1127 case characters<CharT>::sTabChar:
1128 case characters<CharT>::sSpaceChar:
1129 case characters<CharT>::sNewLineChar:
1130 case characters<CharT>::sCarriageReturnChar:
1140 ret.first = aCurrent;
1141 while (aCurrent != aEnd)
1143 CharT current =*aCurrent;
1144 if (!aIgnoreWhitespace)
1148 case characters<CharT>::sTabChar:
1149 case characters<CharT>::sSpaceChar:
1150 case characters<CharT>::sNewLineChar:
1151 case characters<CharT>::sCarriageReturnChar:
1157 if (current == characters<CharT>::sAmpersandChar)
1158 ret.iHasEntities =
true;
1159 if (aDelimeters.find(current))
1164 ret.second = aCurrent;