96 struct ChildIterator {
97 using difference_type = ptrdiff_t;
99 using pointer = value_type*;
100 using reference = value_type&;
101 using iterator_category = std::forward_iterator_tag;
105 const XMLElement& operator*()
const {
return *elem; }
106 ChildIterator& operator++() { elem = elem->nextSibling;
return *
this; }
107 ChildIterator operator++(
int) {
auto result = *
this; elem = elem->nextSibling;
return result; }
108 [[nodiscard]]
bool operator==(
const ChildIterator& i)
const =
default;
110 static_assert(std::forward_iterator<ChildIterator>);
113 [[nodiscard]] ChildIterator
begin()
const {
return {elem->firstChild}; }
114 [[nodiscard]] ChildIterator
end()
const {
return {
nullptr}; }
116 static_assert(std::ranges::range<ChildRange>);
118 struct NamedChildIterator {
119 using difference_type = ptrdiff_t;
121 using pointer = value_type*;
122 using reference = value_type&;
123 using iterator_category = std::forward_iterator_tag;
126 std::string_view name;
128 NamedChildIterator() : elem(
nullptr) {}
129 NamedChildIterator(
const XMLElement* elem_, std::string_view name_)
130 : elem(elem_), name(name_)
132 while (elem && elem->
getName() != name) {
133 elem = elem->nextSibling;
137 const XMLElement* operator*()
const {
return elem; }
138 NamedChildIterator& operator++() {
140 elem = elem->nextSibling;
141 }
while (elem && elem->
getName() != name);
144 NamedChildIterator operator++(
int) {
auto result = *
this; ++(*this);
return result; }
145 [[nodiscard]]
bool operator==(
const NamedChildIterator& i)
const {
return elem == i.elem; }
147 static_assert(std::forward_iterator<NamedChildIterator>);
148 struct NamedChildRange {
150 std::string_view name;
151 [[nodiscard]] NamedChildIterator
begin()
const {
return {elem->firstChild, name}; }
152 [[nodiscard]] NamedChildIterator
end()
const {
return {
nullptr, std::string_view{}}; }
154 static_assert(std::ranges::range<NamedChildRange>);
156 struct AttributeIterator {
157 using difference_type = ptrdiff_t;
159 using pointer = value_type*;
160 using reference = value_type&;
161 using iterator_category = std::forward_iterator_tag;
166 AttributeIterator& operator++() { attr = attr->nextAttribute;
return *
this; }
167 AttributeIterator operator++(
int) {
auto result = *
this; attr = attr->nextAttribute;
return result; }
168 [[nodiscard]]
bool operator==(
const AttributeIterator& i)
const =
default;
170 static_assert(std::forward_iterator<AttributeIterator>);
171 struct AttributeRange {
173 [[nodiscard]] AttributeIterator
begin()
const {
return {elem->firstAttribute}; }
174 [[nodiscard]] AttributeIterator
end()
const {
return {
nullptr}; }
176 static_assert(std::ranges::range<AttributeRange>);
180 XMLElement(
const char* name_,
const char* data_) : name(name_), data(data_) {}
182 [[nodiscard]] std::string_view
getName()
const {
return name; }
185 [[nodiscard]] std::string_view
getData()
const {
186 return data ? std::string_view(data) : std::string_view();
199 [[nodiscard]] std::string_view
getChildData(std::string_view childName)
const;
200 [[nodiscard]] std::string_view
getChildData(std::string_view childName,
201 std::string_view defaultValue)
const;
202 [[nodiscard]]
bool getChildDataAsBool(std::string_view childName,
bool defaultValue)
const;
203 [[nodiscard]]
int getChildDataAsInt(std::string_view childName,
int defaultValue)
const;
207 [[nodiscard]] NamedChildRange
getChildren(std::string_view childName)
const {
return {
this, childName}; }
211 [[nodiscard]] std::string_view
getAttributeValue(std::string_view attrName)
const;
213 std::string_view defaultValue)
const;
215 bool defaultValue)
const;
217 int defaultValue)
const;
229 assert(!nextSibling);
230 nextSibling = sibling;
234 assert(!firstAttribute);
235 firstAttribute = attribute;
241 const char* data =
nullptr;