1 /*============================================================================= 2 Copyright (c) 2017 Daniel James 3 4 Use, modification and distribution is subject to the Boost Software 5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt) 7 =============================================================================*/ 8 9 #if !defined(BOOST_QUICKBOOK_XML_PARSE_HPP) 10 #define BOOST_QUICKBOOK_XML_PARSE_HPP 11 12 #include <list> 13 #include <string> 14 #include "string_view.hpp" 15 #include "tree.hpp" 16 17 namespace quickbook 18 { 19 namespace detail 20 { 21 struct xml_element; 22 typedef tree<xml_element> xml_tree; 23 typedef tree_builder<xml_element> xml_tree_builder; 24 struct xml_parse_error; 25 26 struct xml_element : tree_node<xml_element> 27 { 28 enum element_type 29 { 30 element_node, 31 element_text, 32 element_html 33 } type_; 34 std::string name_; 35 36 private: 37 std::list<std::pair<std::string, std::string> > attributes_; 38 39 public: 40 std::string contents_; 41 xml_elementquickbook::detail::xml_element42 explicit xml_element(element_type n) : type_(n) {} 43 xml_elementquickbook::detail::xml_element44 explicit xml_element(element_type n, quickbook::string_view name) 45 : type_(n), name_(name.begin(), name.end()) 46 { 47 } 48 text_nodequickbook::detail::xml_element49 static xml_element* text_node(quickbook::string_view x) 50 { 51 xml_element* n = new xml_element(element_text); 52 n->contents_.assign(x.begin(), x.end()); 53 return n; 54 } 55 html_nodequickbook::detail::xml_element56 static xml_element* html_node(quickbook::string_view x) 57 { 58 xml_element* n = new xml_element(element_html); 59 n->contents_.assign(x.begin(), x.end()); 60 return n; 61 } 62 nodequickbook::detail::xml_element63 static xml_element* node(quickbook::string_view x) 64 { 65 return new xml_element(element_node, x); 66 } 67 has_attributequickbook::detail::xml_element68 bool has_attribute(quickbook::string_view name) 69 { 70 for (auto it = attributes_.begin(), end = attributes_.end(); 71 it != end; ++it) { 72 if (name == it->first) { 73 return true; 74 } 75 } 76 return false; 77 } 78 get_attributequickbook::detail::xml_element79 string_view get_attribute(quickbook::string_view name) 80 { 81 for (auto it = attributes_.begin(), end = attributes_.end(); 82 it != end; ++it) { 83 if (name == it->first) { 84 return it->second; 85 } 86 } 87 return string_view(); 88 } 89 set_attributequickbook::detail::xml_element90 string_view set_attribute( 91 quickbook::string_view name, quickbook::string_view value) 92 { 93 for (auto it = attributes_.begin(), end = attributes_.end(); 94 it != end; ++it) { 95 if (name == it->first) { 96 it->second.assign(value.begin(), value.end()); 97 return it->second; 98 } 99 } 100 101 attributes_.push_back( 102 std::make_pair(name.to_s(), value.to_s())); 103 return attributes_.back().second; 104 } 105 get_childquickbook::detail::xml_element106 xml_element* get_child(quickbook::string_view name) 107 { 108 for (auto it = children(); it; it = it->next()) { 109 if (it->type_ == element_node && it->name_ == name) { 110 return it; 111 } 112 } 113 114 return 0; 115 } 116 }; 117 118 struct xml_parse_error 119 { 120 char const* message; 121 string_iterator pos; 122 xml_parse_errorquickbook::detail::xml_parse_error123 xml_parse_error(char const* m, string_iterator p) 124 : message(m), pos(p) 125 { 126 } 127 }; 128 129 void write_xml_tree(xml_element*); 130 xml_tree xml_parse(quickbook::string_view); 131 } 132 } 133 134 #endif 135