8 #ifndef INCLUDED_ORCUS_SAX_NS_PARSER_HPP
9 #define INCLUDED_ORCUS_SAX_NS_PARSER_HPP
11 #include "sax_parser.hpp"
12 #include "xml_namespace.hpp"
14 #include <unordered_set>
48 namespace sax {
namespace detail {
53 std::string_view name;
55 entity_name(std::string_view _ns, std::string_view _name) :
56 ns(_ns), name(_name) {}
60 return other.ns == ns && other.name == name;
67 std::hash<std::string_view> hasher;
68 return hasher(v.ns) + hasher(v.name);
73 typedef std::unordered_set<std::string_view> ns_keys_type;
74 typedef std::unordered_set<entity_name, entity_name::hash> entity_names_type;
79 std::string_view name;
87 using elem_scopes_type = std::vector<elem_scope>;
177 void attribute(std::string_view name, std::string_view val)
211 template<
typename HandlerT>
215 typedef HandlerT handler_type;
233 class handler_wrapper
235 sax::detail::elem_scopes_type m_scopes;
236 sax::detail::ns_keys_type m_ns_keys;
237 sax::detail::entity_names_type m_attrs;
243 handler_type& m_handler;
248 handler_wrapper(
xmlns_context& ns_cxt, handler_type& handler) : m_ns_cxt(ns_cxt), m_handler(handler), m_declaration(false) {}
252 m_handler.doctype(dtd);
255 void start_declaration(std::string_view name)
257 m_declaration =
true;
258 m_handler.start_declaration(name);
261 void end_declaration(std::string_view name)
263 m_declaration =
false;
264 m_handler.end_declaration(name);
267 void start_element(
const sax::parser_element& elem)
269 m_scopes.emplace_back();
270 sax::detail::elem_scope& scope = m_scopes.back();
271 scope.ns = m_ns_cxt.
get(elem.ns);
272 scope.name = elem.name;
273 scope.ns_keys.swap(m_ns_keys);
275 m_elem.
ns = scope.ns;
277 m_elem.
name = scope.name;
280 m_handler.start_element(m_elem);
285 void end_element(
const sax::parser_element& elem)
287 sax::detail::elem_scope& scope = m_scopes.back();
288 if (scope.ns != m_ns_cxt.
get(elem.ns) || scope.name != elem.name)
289 throw malformed_xml_error(
"mis-matching closing element.", -1);
291 m_elem.
ns = scope.ns;
293 m_elem.
name = scope.name;
296 m_handler.end_element(m_elem);
299 for (
const std::string_view& key : scope.ns_keys)
305 void characters(std::string_view val,
bool transient)
307 m_handler.characters(val,
transient);
310 void attribute(
const sax::parser_attribute& attr)
315 m_handler.attribute(attr.name, attr.value);
319 if (m_attrs.count(sax::detail::entity_name(attr.ns, attr.name)) > 0)
320 throw malformed_xml_error(
321 "You can't define two attributes of the same name in the same element.", -1);
323 m_attrs.insert(sax::detail::entity_name(attr.ns, attr.name));
325 if (attr.ns.empty() && attr.name ==
"xmlns")
328 m_ns_cxt.
push(std::string_view{}, attr.value);
329 m_ns_keys.insert(std::string_view{});
333 if (attr.ns ==
"xmlns")
336 if (!attr.name.empty())
338 m_ns_cxt.
push(attr.name, attr.value);
339 m_ns_keys.insert(attr.name);
344 m_attr.
ns = attr.ns.empty() ? XMLNS_UNKNOWN_ID : m_ns_cxt.
get(attr.ns);
346 m_attr.
name = attr.name;
347 m_attr.
value = attr.value;
349 m_handler.attribute(m_attr);
354 handler_wrapper m_wrapper;
355 sax_parser<handler_wrapper> m_parser;
358 template<
typename HandlerT>
359 sax_ns_parser<HandlerT>::sax_ns_parser(
360 std::string_view content, xmlns_context& ns_cxt, handler_type& handler) :
361 m_wrapper(ns_cxt, handler), m_parser(content, m_wrapper)
365 template<
typename HandlerT>
Definition: sax_ns_parser.hpp:92
void attribute(std::string_view name, std::string_view val)
Definition: sax_ns_parser.hpp:177
void attribute(const orcus::sax_ns_parser_attribute &attr)
Definition: sax_ns_parser.hpp:191
void start_element(const orcus::sax_ns_parser_element &elem)
Definition: sax_ns_parser.hpp:131
void characters(std::string_view val, bool transient)
Definition: sax_ns_parser.hpp:160
void start_declaration(std::string_view decl)
Definition: sax_ns_parser.hpp:111
void doctype(const orcus::sax::doctype_declaration &dtd)
Definition: sax_ns_parser.hpp:99
void end_element(const orcus::sax_ns_parser_element &elem)
Definition: sax_ns_parser.hpp:141
void end_declaration(std::string_view decl)
Definition: sax_ns_parser.hpp:121
Definition: sax_ns_parser.hpp:213
void parse()
Definition: sax_ns_parser.hpp:366
Definition: xml_namespace.hpp:100
xmlns_id_t push(std::string_view alias, std::string_view uri)
xmlns_id_t get(std::string_view alias) const
void pop(std::string_view alias)
Definition: sax_ns_parser.hpp:77
Definition: sax_ns_parser.hpp:64
Definition: sax_ns_parser.hpp:51
Definition: sax_parser_base.hpp:37
Definition: sax_ns_parser.hpp:35
std::string_view value
Definition: sax_ns_parser.hpp:43
xmlns_id_t ns
Definition: sax_ns_parser.hpp:37
bool transient
Definition: sax_ns_parser.hpp:45
std::string_view name
Definition: sax_ns_parser.hpp:41
std::string_view ns_alias
Definition: sax_ns_parser.hpp:39
Definition: sax_ns_parser.hpp:21
std::ptrdiff_t end_pos
Definition: sax_ns_parser.hpp:31
xmlns_id_t ns
Definition: sax_ns_parser.hpp:23
std::string_view name
Definition: sax_ns_parser.hpp:27
std::string_view ns_alias
Definition: sax_ns_parser.hpp:25
std::ptrdiff_t begin_pos
Definition: sax_ns_parser.hpp:29