DocWire SDK
DocWire SDK: Deterministic, auditable, and secure data processing in C++20. On-premise by default. No compromises on computational speed.
Loading...
Searching...
No Matches
xml_attributes.h
1/*********************************************************************************************************************************************/
2/* DocWire SDK: Award-winning modern data processing in C++20. SourceForge Community Choice & Microsoft support. AI-driven processing. */
3/* Supports nearly 100 data formats, including email boxes and OCR. Boost efficiency in text extraction, web data extraction, data mining, */
4/* document analysis. Offline processing possible for security and confidentiality */
5/* */
6/* Copyright (c) SILVERCODERS Ltd, http://silvercoders.com */
7/* Project homepage: https://github.com/docwire/docwire */
8/* */
9/* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-DocWire-Commercial */
10/*********************************************************************************************************************************************/
11
12#ifndef DOCWIRE_XML_ATTRIBUTES_H
13#define DOCWIRE_XML_ATTRIBUTES_H
14
15#include "safety_policy.h"
16#include "xml_node_ref.h"
17#include "xml_attribute_ref.h"
18#include "sentinel.h"
19#include "checked.h"
20#include "convert_base.h"
21#include <algorithm>
22#include <optional>
23#include <ranges>
24
28namespace docwire::xml
29{
30
39template <safety_policy safety_level = default_safety_level>
40class attributes_view : public std::ranges::view_base
41{
42public:
43 class iterator;
44 iterator begin() const { return iterator{m_reader}; }
49 ~attributes_view() noexcept(noexcept(m_reader.get().move_to_element()))
50 {
51 m_reader.get().move_to_element();
52 }
53 sentinel end() const { return {}; }
54
60private:
61 std::reference_wrapper<reader<safety_level>> m_reader;
62};
63
72template<safety_policy safety_level>
77
87template<safety_policy safety_level>
88checked<std::optional<std::string_view>, safety_level> attribute_value(const node_ref<safety_level>& node, std::string_view name)
89{
90 auto attrs = attributes<safety_level>(node);
91 if (auto it = std::ranges::find_if(attrs, [name](const auto& attr) { return attr.name() == name; }); it != attrs.end())
92 return (*it).value();
93 return std::nullopt;
94}
95
106template<typename T, safety_policy safety_level>
108checked<std::optional<T>, safety_level> attribute_value(const node_ref<safety_level>& node, std::string_view name)
109{
110 if (auto sv = attribute_value(node, name))
111 return convert::try_to<T>(*sv);
112 return std::nullopt;
113}
114
118template<safety_policy safety_level>
119class attributes_view<safety_level>::iterator
120{
121public:
122 using iterator_concept = std::input_iterator_tag;
123 using difference_type = std::ptrdiff_t;
124 using value_type = attribute_ref<safety_level>;
125 using pointer = const value_type*;
126 using reference = const value_type&;
127
128 bool operator==(const sentinel&) const {
129 return !m_attribute.has_value();
130 }
131
132 reference operator*() const {
133 return *m_attribute;
134 }
135
136 pointer operator->() const {
137 return &operator*();
138 }
139
140 iterator& operator++() {
141 if (m_attribute.has_value() && !m_reader.get().move_to_next_attribute()) {
142 m_attribute.reset();
143 }
144 return *this;
145 }
146
147 void operator++(int) {
148 ++(*this);
149 }
150
151private:
152 friend class attributes_view<safety_level>;
153 explicit iterator(std::reference_wrapper<reader<safety_level>> reader)
154 : m_reader(reader) {
155 if (m_reader.get().move_to_first_attribute()) {
156 m_attribute.emplace(m_reader.get());
157 }
158 }
159 std::reference_wrapper<reader<safety_level>> m_reader;
160 checked<std::optional<value_type>, safety_level> m_attribute; // The presence of a value indicates a valid iterator.
161};
162
163} // namespace docwire::xml
164
165#endif // DOCWIRE_XML_ATTRIBUTES_H
A generic wrapper for dereferenceable types (like pointers and optionals) that provides checked acces...
Definition checked.h:39
A reference to an XML attribute.
Iterator for traversing XML attributes.
A view over the attributes of an XML node.
~attributes_view() noexcept(noexcept(m_reader.get().move_to_element()))
Destructor. Moves the reader back to the element containing the attributes to ensure consistent state...
attributes_view(reader< safety_level > &reader)
Constructs a view from a reader.
A reference to the current XML node in the reader.
const not_null< std::shared_ptr< iterator_state< safety_level > >, safety_level > & state() const
Returns the shared iterator state associated with this node reference.
A forward-only, non-cached XML reader.
Definition xml_reader.h:64
constexpr std::optional< To > try_to(const From &from) noexcept
Tries to convert a value of type From to type To.
XML processing utilities.
checked< std::optional< std::string_view >, safety_level > attribute_value(const node_ref< safety_level > &node, std::string_view name)
A convenience helper to find an attribute by name.
attributes_view< safety_level > attributes(const node_ref< safety_level > &node)
A factory function to create an attributes_view with a specified safety policy.
A sentinel type used to define the end of a range or view.
Definition sentinel.h:23