#include "example/common/book_xml.h" #include #include #include #include "example/common/book.h" // ----------------------------------------------------------------------------- // Print a XML node to string. static std::string PrintXml(pugi::xml_node xnode, bool format_raw = true, const char* indent = "") { std::stringstream ss; unsigned int flags = format_raw ? pugi::format_raw : pugi::format_indent; xnode.print(ss, indent, flags); return ss.str(); } // ----------------------------------------------------------------------------- bool XmlToBook(pugi::xml_node xbook, Book* book) { assert(xbook.name() == std::string("book")); book->id = xbook.child("id").text().as_string(); book->title = xbook.child("title").text().as_string(); book->price = xbook.child("price").text().as_double(); return true; } void BookToXml(const Book& book, pugi::xml_node* xparent) { pugi::xml_node xbook = xparent->append_child("book"); xbook.append_child("id").text().set(book.id.c_str()); xbook.append_child("title").text().set(book.title.c_str()); xbook.append_child("price").text().set(book.price); } bool XmlToBookList(pugi::xml_node xbooks, std::list* books) { assert(xbooks.name() == std::string("books")); pugi::xml_node xbook = xbooks.child("book"); while (xbook) { Book book{ xbook.child("id").text().as_string(), xbook.child("title").text().as_string(), xbook.child("price").text().as_double() }; books->push_back(book); xbook = xbook.next_sibling("book"); } return true; } void BookListToXml(const std::list& books, pugi::xml_node* xparent) { pugi::xml_node xbooks = xparent->append_child("books"); for (const Book& book : books) { BookToXml(book, &xbooks); } } bool XmlStringToBook(const std::string& xml_string, Book* book) { pugi::xml_document xdoc; if (!xdoc.load_string(xml_string.c_str())) { return false; } pugi::xml_node xbook = xdoc.document_element(); if (!xbook) { return false; } if (xbook.name() != std::string("book")) { return false; } return XmlToBook(xbook, book); } std::string BookToXmlString(const Book& book, bool format_raw, const char* indent) { pugi::xml_document xdoc; BookToXml(book, &xdoc); return PrintXml(xdoc); } // ----------------------------------------------------------------------------- std::string NewRequestXml(const Book& book) { pugi::xml_document xdoc; pugi::xml_node xwebcc = xdoc.append_child("webcc"); xwebcc.append_attribute("type") = "request"; BookToXml(book, &xwebcc); return PrintXml(xdoc, false, " "); } // ----------------------------------------------------------------------------- static std::string __NewResultXml(int code, const char* message, std::function callback) { pugi::xml_document xdoc; pugi::xml_node xwebcc = xdoc.append_child("webcc"); xwebcc.append_attribute("type") = "response"; pugi::xml_node xstatus = xwebcc.append_child("status"); xstatus.append_attribute("code") = code; xstatus.append_attribute("message") = message; if (callback) { callback(&xwebcc); } return PrintXml(xdoc, false, " "); } std::string NewResultXml(int code, const char* message) { return __NewResultXml(code, message, {}); } std::string NewResultXml(int code, const char* message, const char* node, const char* key, const char* value) { auto callback = [node, key, value](pugi::xml_node* xparent) { pugi::xml_node xnode = xparent->append_child(node); xnode.append_child(key).text() = value; }; return __NewResultXml(code, message, callback); } std::string NewResultXml(int code, const char* message, const Book& book) { return __NewResultXml(code, message, std::bind(BookToXml, book, std::placeholders::_1)); } std::string NewResultXml(int code, const char* message, const std::list& books) { return __NewResultXml(code, message, std::bind(BookListToXml, books, std::placeholders::_1)); }