7 #ifndef ZEN_XML_BIND_HEADER_9081740816593478258435
8 #define ZEN_XML_BIND_HEADER_9081740816593478258435
11 #include "cvrt_struc.h"
32 template <
class String>
inline
51 template <
class String>
inline
53 const String& filename,
54 const std::string& lineBreak =
"\r\n",
55 const std::string& indent =
" ")
57 std::string stream =
serialize(doc, lineBreak, indent);
101 template <
class String>
104 const std::string utf8name = utfCvrtTo<std::string>(name);
106 return child ? *child : ref_->
addChild(utf8name);
142 template <
class String,
class T>
157 struct ConversionToBool {
int dummy; };
171 XmlIn(
const XmlDoc& doc) : refIndex(0), log(std::make_shared<ErrorLog>()) { refList.push_back(&doc.
root()); }
176 XmlIn(
const XmlElement* element) : refIndex(0), log(std::make_shared<ErrorLog>()) { refList.push_back(element); }
181 XmlIn(
const XmlElement& element) : refIndex(0), log(std::make_shared<ErrorLog>()) { refList.push_back(&element); }
189 template <
class String>
192 std::vector<const XmlElement*> childList;
194 if (refIndex < refList.size())
196 auto iterPair = refList[refIndex]->getChildren(name);
197 std::for_each(iterPair.first, iterPair.second,
198 [&](
const XmlElement& child) { childList.push_back(&child); });
201 return XmlIn(childList, childList.empty() ? getChildNameFormatted(name) : std::string(), log);
236 if (refIndex < refList.size())
238 bool success =
readStruc(*refList[refIndex], value);
240 log->notifyConversionError(getNameFormatted());
245 log->notifyMissingElement(getNameFormatted());
268 template <
class String,
class T>
271 if (refIndex < refList.size())
273 bool success = refList[refIndex]->getAttribute(name, value);
275 log->notifyMissingAttribute(getNameFormatted(), utfCvrtTo<std::string>(name));
280 log->notifyMissingElement(getNameFormatted());
286 const XmlElement*
get()
const {
return refIndex < refList.size() ? refList[refIndex] :
nullptr; }
298 operator int ConversionToBool::* ()
const {
return get() ? &ConversionToBool::dummy :
nullptr; }
327 template <
class String>
330 std::vector<String> output;
331 const auto& elements = log->elementList();
332 std::transform(elements.begin(), elements.end(), std::back_inserter(output), [](
const std::string& str) {
return utfCvrtTo<String>(str); });
337 XmlIn(
const std::vector<const XmlElement*>& siblingList,
const std::string& elementNameFmt,
const std::shared_ptr<ErrorLog>& sharedlog) :
338 refList(siblingList), refIndex(0), formattedName(elementNameFmt), log(sharedlog)
339 { assert((!siblingList.empty() && elementNameFmt.empty()) || (siblingList.empty() && !elementNameFmt.empty())); }
341 static std::string getNameFormatted(
const XmlElement& elem)
343 return (elem.parent() ? getNameFormatted(*elem.parent()) +
" " : std::string()) +
"<" + elem.getNameAs<std::string>() +
">";
346 std::string getNameFormatted()
const
348 if (refIndex < refList.size())
350 assert(formattedName.empty());
351 return getNameFormatted(*refList[refIndex]);
354 return formattedName;
357 std::string getChildNameFormatted(
const std::string& childName)
const
359 std::string parentName = getNameFormatted();
360 return (parentName.empty() ? std::string() : (parentName +
" ")) +
"<" + childName +
">";
366 void notifyConversionError (
const std::string& formattedName) { insert(formattedName); }
367 void notifyMissingElement (
const std::string& formattedName) { insert(formattedName); }
368 void notifyMissingAttribute(
const std::string& formattedName,
const std::string& attribName) { insert(formattedName +
" @" + attribName); }
370 const std::vector<std::string>& elementList()
const {
return failedElements; }
373 void insert(
const std::string& newVal)
375 if (usedElements.insert(newVal).second)
376 failedElements.push_back(newVal);
379 std::vector<std::string> failedElements;
380 std::set<std::string> usedElements;
383 std::vector<const XmlElement*> refList;
385 std::string formattedName;
386 std::shared_ptr<ErrorLog> log;
390 #endif //ZEN_XML_BIND_HEADER_9081740816593478258435
bool errorsOccured() const
Notifies errors while mapping the XML to user data.
Definition: bind.h:320
void save(const XmlDoc &doc, const String &filename, const std::string &lineBreak="\r\n", const std::string &indent=" ")
Save XML document to a file.
Definition: bind.h:52
const XmlElement & root() const
Get a const reference to the document's root element.
Definition: dom.h:267
XmlDoc parse(const std::string &stream)
Load XML document from a byte stream.
Definition: parser.h:612
std::string serialize(const XmlDoc &doc, const std::string &lineBreak="\r\n", const std::string &indent=" ")
Save XML document as a byte stream.
Definition: parser.h:287
XmlOut(XmlDoc &doc)
Construct an output proxy for an XML document.
Definition: bind.h:88
XmlElement & ref()
Return a reference to the underlying Xml element.
Definition: bind.h:146
void saveStream(const std::string &stream, const String &filename)
Save byte stream to a file.
Definition: io.h:66
Proxy class to conveniently convert XML structure to user data.
Definition: bind.h:154
void operator()(const T &value)
Write user data to the underlying XML element.
Definition: bind.h:115
std::string loadStream(const String &filename)
Load byte stream from a file.
Definition: io.h:94
XmlIn(const XmlDoc &doc)
Construct an input proxy for an XML document.
Definition: bind.h:171
XmlIn(const XmlElement &element)
Construct an input proxy for a single XML element.
Definition: bind.h:181
void next()
Refer to next sibling element with the same name.
Definition: bind.h:225
An XML element.
Definition: dom.h:21
void attribute(const String &name, const T &value)
Write user data to an XML attribute.
Definition: bind.h:143
XmlIn operator[](const String &name) const
Retrieve a handle to an XML child element for reading.
Definition: bind.h:190
The complete XML document.
Definition: dom.h:249
bool attribute(const String &name, T &value) const
Read user data from an XML attribute.
Definition: bind.h:269
std::vector< String > getErrorsAs() const
Get a list of XML element and attribute names which failed to convert to user data.
Definition: bind.h:328
Proxy class to conveniently convert user data into XML structure.
Definition: bind.h:63
bool operator()(T &value) const
Read user data from the underlying XML element.
Definition: bind.h:234
XmlElement & addChild(const String &name)
Create a new child element and return a reference to it.
Definition: dom.h:97
const XmlElement * getChild(const String &name) const
Retrieve a child element with the given name.
Definition: dom.h:113
bool readStruc(const XmlElement &input, T &value)
Convert XML element to structured user data.
Definition: cvrt_struc.h:205
void setAttribute(const String &name, const T &value)
Create or update an XML attribute.
Definition: dom.h:77
void writeStruc(const T &value, XmlElement &output)
Convert structured user data into an XML element.
Definition: cvrt_struc.h:198
XmlOut operator[](const String &name) const
Retrieve a handle to an XML child element for writing.
Definition: bind.h:102
XmlIn(const XmlElement *element)
Construct an input proxy for a single XML element, may be nullptr.
Definition: bind.h:176
XmlOut(XmlElement &element)
Construct an output proxy for a single XML element.
Definition: bind.h:93
XmlDoc load(const String &filename)
Load XML document from a file.
Definition: bind.h:33