2 #include <samchon/HashMap.hpp> 10 #include <samchon/WeakString.hpp> 11 #include <samchon/library/Math.hpp> 18 typedef std::vector<std::shared_ptr<XML>> XMLList;
70 :
public HashMap<std::string, std::shared_ptr<XMLList>>
108 property_map_ = xml.property_map_;
111 for (
auto it = xml.begin(); it != xml.end(); it++)
113 if (it->second->empty() ==
true)
116 std::shared_ptr<XMLList> xmlList(
new XMLList());
117 xmlList->reserve(it->second->size());
119 for (
size_t i = 0; i < it->second->size(); it++)
120 xmlList->emplace_back(
new XML(*it->second->at(i)));
122 this->
set(xmlList->at(0)->tag_, xmlList);
131 tag_ = move(xml.tag_);
132 value_ = move(xml.value_);
134 property_map_ = move(xml.property_map_);
146 if (wstr.
find(
'<') == std::string::npos)
150 std::string replacedStr;
151 if (wstr.
find(
"<!--") != std::string::npos)
153 std::queue<std::pair<size_t, size_t>> indexPairQueue;
154 size_t beginX = 0, endX;
157 replacedStr.reserve(wstr.
size());
158 while ((beginX = wstr.
find(
"<!--", beginX)) != std::string::npos)
160 indexPairQueue.push({ beginX, wstr.
find(
"-->", beginX + 1) + 3 });
166 while (indexPairQueue.empty() ==
false)
168 endX = indexPairQueue.front().first;
169 replacedStr.append(wstr.
substring(beginX, endX).str());
171 beginX = indexPairQueue.front().second;
172 indexPairQueue.pop();
174 replacedStr.append(wstr.
substr(beginX).str());
181 if (wstr.
find(
"<?xml") != std::string::npos)
199 parse_properties(wstr);
201 if (parse_value(wstr) ==
true)
202 parse_children(wstr);
207 size_t startX = wstr.
find(
"<") + 1;
212 wstr.
find(
' ', startX),
213 wstr.
find(
"\r\n", startX),
214 wstr.
find(
'\n', startX),
215 wstr.
find(
'\t', startX),
216 wstr.
find(
'>', startX),
217 wstr.
find(
'/', startX)
222 tag_ = move( wstr.
substring(startX, endX).str() );
241 QuotePair(TYPE type,
size_t start_index,
size_t end_index)
244 this->start_index = start_index;
245 this->end_index = end_index;
249 size_t i_begin = wstr.
find(
'<' + tag_) + tag_.size() + 1;
250 size_t i_endSlash = wstr.
rfind(
'/');
251 size_t i_endBlock = wstr.
find(
'>', i_begin);
253 size_t i_end = calc_min_index({ i_endSlash, i_endBlock });
254 if (i_end == std::string::npos || i_begin >= i_end)
260 if (line.
find(
'=') == std::string::npos)
263 std::string label, value;
264 std::vector<QuotePair*> helpers;
265 bool inQuote =
false;
266 QuotePair::TYPE type;
267 size_t startPoint, equalPoint;
270 for (i = 0; i < line.
size(); i++)
273 if (inQuote ==
false && (line[i] ==
'\'' || line[i] ==
'"'))
279 type = QuotePair::SINGLE;
280 else if (line[i] ==
'"')
281 type = QuotePair::DOUBLE;
287 (type == QuotePair::SINGLE && line[i] ==
'\'') ||
288 (type == QuotePair::DOUBLE && line[i] ==
'"')
292 helpers.push_back(
new QuotePair(type, startPoint, i));
296 for (i = 0; i < helpers.size(); i++)
300 equalPoint = (
long long)line.
find(
'=');
301 label = move( line.
substring(0, equalPoint).trim().str() );
305 equalPoint = line.
find(
'=', helpers[i - 1]->end_index + 1);
306 label = line.
substring(helpers[i - 1]->end_index + 1, equalPoint).trim().str();
316 helpers[i]->start_index + 1,
317 helpers[i]->end_index
323 property_map_.
set(label, move(value));
325 for (i = 0; i < helpers.size(); i++)
331 size_t i_endSlash = wstr.
rfind(
'/');
332 size_t i_endBlock = wstr.
find(
'>');
334 if (i_endSlash < i_endBlock || i_endBlock + 1 == wstr.
rfind(
'<'))
342 size_t startX = i_endBlock + 1;
343 size_t endX = wstr.
rfind(
'<');
346 if (wstr.
find(
'<') == std::string::npos)
347 value_ = wstr.trim();
356 if (wstr.
find(
'<') == std::string::npos)
359 size_t startX = wstr.
find(
'<');
360 size_t endX = wstr.
rfind(
'>') + 1;
367 int blockStartCount = 0;
368 int blockEndCount = 0;
374 for (i = 0; i < wstr.
size(); i++)
376 if (wstr[i] ==
'<' && wstr.
substr(i, 2) !=
"</")
378 else if (wstr.
substr(i, 2) ==
"/>" || wstr.
substr(i, 2) ==
"</")
381 if (blockStartCount >= 1 && blockStartCount == blockEndCount)
384 end = wstr.
find(
'>', i);
389 std::shared_ptr<XML> xml(
new XML(
this, wstr.
substring(start, end + 1)));
463 return property_map_.
has(key);
479 return property_map_;
495 template<
class T = std::
string>
auto getValue() const -> T
497 double val = std::stod(value_);
502 template<>
auto getValue()
const ->
bool 504 return value_ ==
"true";
507 template<>
auto getValue()
const -> std::string
537 template<
class T = std::
string>
auto getProperty(
const std::string &key)
const -> T
539 double val = std::stod(property_map_.
get(key));
544 template<>
auto getProperty(
const std::string &key)
const ->
bool 546 const std::string &val = property_map_.
get(key);
548 return val ==
"true" || val ==
"1";
551 template<>
auto getProperty(
const std::string &key)
const -> std::string
553 return property_map_.
get(key);
557 return property_map_.
get(key);
580 auto findProperty(
const std::string &key) ->HashMap<std::string, std::string>::iterator
582 return property_map_.find(key);
587 return property_map_.find(key);
590 template <
typename T = std::
string>
591 auto fetchProperty(
const std::string &key,
const T &def = T())
const -> T
594 return getProperty<T>(key);
634 template <
typename T>
637 value_ = std::to_string(val);
640 template<>
void setValue(
const bool &flag)
642 this->value_ = flag ?
"true" :
"false";
645 template<>
void setValue(
const std::string &val)
651 this->value_ = val.
str();
684 property_map_.
set(key, std::to_string(val));
687 template<>
void setProperty(
const std::string &key,
const bool &flag)
689 property_map_.
set(key, flag ?
"true" :
"false");
692 template<>
void setProperty(
const std::string &key,
const std::string &val)
694 property_map_.
set(key, val);
698 property_map_.
set(key, val.
str());
700 void setProperty(
const std::string &key,
const char *ptr)
702 property_map_.
set(key, ptr);
715 if (wstr.
empty() ==
true)
718 std::shared_ptr<XML> xml(
new XML(
this, wstr));
719 auto it = find(xml->tag_);
724 set(xml->tag_, std::make_shared<XMLList>());
725 it = find(xml->tag_);
729 it->second->push_back(xml);
739 std::string &tag = xml->tag_;
741 if (this->
has(tag) ==
false)
742 this->
set(tag, std::make_shared<XMLList>());
747 template <
typename T>
748 void insertValue(
const std::string &tag,
const T &val)
750 std::shared_ptr<XML> xml(
new XML());
783 for (
auto it = xml->property_map_.begin(); it != xml->property_map_.end(); it++)
784 property_map_[it->first] = it->second;
805 property_map_.erase(key);
821 property_map_.clear();
828 auto calc_min_index(
const std::vector<size_t> &vec)
const ->
size_t 830 size_t val = std::string::npos;
831 for (
size_t i = 0; i < vec.size(); i++)
832 if (vec[i] != std::string::npos && vec[i] < val)
838 auto encode_value(
const WeakString &wstr)
const -> std::string
840 static std::vector<std::pair<std::string, std::string>> pairArray =
850 auto decode_value(
const WeakString &wstr)
const -> std::string
852 static std::vector<std::pair<std::string, std::string>> pairArray =
862 auto encode_property(
const WeakString &wstr)
const -> std::string
864 static std::vector<std::pair<std::string, std::string>> pairArray =
876 return wstr.trim().replaceAll(pairArray);
879 auto decodeProperty(
const WeakString &wstr)
const -> std::string
881 static std::vector<std::pair<std::string, std::string>> pairArray =
911 std::string str = std::string(level,
'\t') +
"<" + tag_;
914 for (
auto it = property_map_.begin(); it != property_map_.end(); it++)
915 str +=
" " + it->first +
"=\"" + encode_property(it->second) +
"\"";
917 if (this->empty() ==
true)
920 if (value_.empty() ==
true)
923 str +=
">" + encode_value(value_) +
"</" + tag_ +
">";
930 for (
auto it = begin(); it != end(); it++)
931 for (
size_t i = 0; i < it->second->size(); i++)
932 str += it->second->at(i)->toString(level + 1);
934 str += std::string(level,
'\t') +
"</" + tag_ +
">";
auto str() const -> std::string
Get the string content.
auto has(const Key &key) const -> bool
Whether have the item or not.
auto empty() const -> bool
Tests wheter string is emtpy.
auto toString(size_t level=0) const -> std::string
auto replaceAll(const WeakString &before, const WeakString &after) const -> std::string
Returns a string specified word is replaced.
void eraseProperty(const std::string &key)
auto findProperty(const std::string &key) -> HashMap< std::string, std::string >::iterator
void insertAllProperties(const std::shared_ptr< XML > xml)
auto get(const Key &key) -> T &
Get element.
XML()
Default Constructor.
auto between(const WeakString &start={}, const WeakString &end={}) const -> WeakString
Generates a substring.
auto getTag() const -> std::string
Get tag.
auto substring(size_t startIndex, size_t endIndex=SIZE_MAX) const -> WeakString
Generates a substring.
XML(XML &&xml)
Move Constructor.
auto find(const WeakString &delim, size_t startIndex=NULL) const -> size_t
Finds first occurence in string.
void setProperty(const std::string &key, const T &val)
auto getValue() const -> T
Get value.
void push_back(const std::shared_ptr< XML > xml)
Add children xml.
void setTag(const std::string &val)
auto getPropertyMap() const -> const HashMap< std::string, std::string > &
auto substr(size_t startIndex, size_t size=SIZE_MAX) const -> WeakString
Generates a substring.
void push_back(WeakString wstr)
Add children xml objects by string representing them.
auto getProperty(const std::string &key) const -> T
Get property.
XML(const XML &xml)
Copy Constructor.
void set(const Key &key, const T &val)
Set element.
auto hasProperty(const std::string &key) const -> bool
void setValue(const T &val)
auto size() const -> size_t
Returns size of the characters which are being referenced.
auto rfind(const WeakString &delim, size_t endIndex=SIZE_MAX) const -> size_t
Finds last occurence in string.
Customized std::unordered_map.
A string class only references characeters, reference only.