MUSX Document Model
Loading...
Searching...
No Matches
PugiXmlImpl.h
1/*
2 * Copyright (C) 2025, Robert Patterson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22#pragma once
23
24#ifdef MUSX_USE_PUGIXML
25
26#include <string>
27#include <memory>
28#include <exception>
29#include "pugixml.hpp"
30#include "XmlInterface.h"
31
32namespace musx {
33namespace xml {
34
43namespace pugi {
44
49 const ::pugi::xml_attribute m_attribute;
50
51public:
55 explicit Attribute(::pugi::xml_attribute attr) : m_attribute(attr) {}
56
57 std::string getName() const override { return m_attribute.name(); }
58 std::string getValue() const override { return m_attribute.value(); }
59
60 std::shared_ptr<IXmlAttribute> nextAttribute() const override {
61 ::pugi::xml_attribute next = m_attribute.next_attribute();
62 return next ? std::make_shared<Attribute>(next) : nullptr;
63 }
64};
65
70 const ::pugi::xml_node m_element;
71
72 static const char* tagPtr(const std::string& tagName) {
73 return tagName.empty() ? nullptr : tagName.c_str();
74 }
75
76public:
80 explicit Element(::pugi::xml_node elem) : m_element(elem) {}
81
82 std::string getTagName() const override { return m_element.name(); }
83
84 std::string getText() const override {
85 return m_element.child_value();
86 }
87
88 std::shared_ptr<IXmlAttribute> getFirstAttribute() const override {
89 ::pugi::xml_attribute attr = m_element.first_attribute();
90 return attr ? std::make_shared<Attribute>(attr) : nullptr;
91 }
92
93 std::shared_ptr<IXmlAttribute> findAttribute(const std::string& name) const override {
94 ::pugi::xml_attribute attr = m_element.attribute(name.c_str());
95 return attr ? std::make_shared<Attribute>(attr) : nullptr;
96 }
97
98 std::shared_ptr<IXmlElement> getFirstChildElement(const std::string& tagName = {}) const override {
99 ::pugi::xml_node child = tagPtr(tagName) ? m_element.child(tagPtr(tagName)) : m_element.first_child();
100 return child ? std::make_shared<Element>(child) : nullptr;
101 }
102
103 std::shared_ptr<IXmlElement> getNextSibling(const std::string& tagName = {}) const override {
104 ::pugi::xml_node sibling = tagPtr(tagName) ? m_element.next_sibling(tagPtr(tagName)) : m_element.next_sibling();
105 return sibling ? std::make_shared<Element>(sibling) : nullptr;
106 }
107
108 std::shared_ptr<IXmlElement> getPreviousSibling(const std::string& tagName = {}) const override {
109 ::pugi::xml_node sibling = tagPtr(tagName) ? m_element.previous_sibling(tagPtr(tagName)) : m_element.previous_sibling();
110 return sibling ? std::make_shared<Element>(sibling) : nullptr;
111 }
112
113 std::shared_ptr<IXmlElement> getParent() const override {
114 ::pugi::xml_node parent = m_element.parent();
115 return parent && parent.type() == ::pugi::node_element ? std::make_shared<Element>(parent) : nullptr;
116 }
117};
118
123 ::pugi::xml_document m_document;
124
125public:
126 void loadFromString(const std::string& xmlContent) override {
127 ::pugi::xml_parse_result result = m_document.load_string(xmlContent.c_str());
128 if (!result) {
129 throw musx::xml::load_error(result.description());
130 }
131 }
132
133 void loadFromString(const std::vector<char>& xmlContent) override {
134 ::pugi::xml_parse_result result = m_document.load_buffer(xmlContent.data(), xmlContent.size());
135 if (!result) {
136 throw musx::xml::load_error(result.description());
137 }
138 }
139
140 std::shared_ptr<IXmlElement> getRootElement() const override {
141 ::pugi::xml_node root = m_document.document_element();
142 return root ? std::make_shared<Element>(root) : nullptr;
143 }
144};
145
146} // namespace pugi
147} // namespace xml
148} // namespace musx
149
150#endif // MUSX_USE_PUGIXML
Interface for an XML attribute.
Definition XmlInterface.h:65
Interface for an XML document.
Definition XmlInterface.h:230
Interface for an XML element.
Definition XmlInterface.h:133
Exception for load xml error.
Definition XmlInterface.h:46
Implementation of IXmlAttribute using PugiXML.
Definition PugiXmlImpl.h:48
std::string getValue() const override
Gets the value of the attribute.
Definition PugiXmlImpl.h:58
std::shared_ptr< IXmlAttribute > nextAttribute() const override
Advances to the next attribute.
Definition PugiXmlImpl.h:60
std::string getName() const override
Gets the name of the attribute.
Definition PugiXmlImpl.h:57
Attribute(::pugi::xml_attribute attr)
Constructor.
Definition PugiXmlImpl.h:55
Implementation of IXmlDocument using PugiXML.
Definition PugiXmlImpl.h:122
void loadFromString(const std::string &xmlContent) override
Loads XML content from a string.
Definition PugiXmlImpl.h:126
std::shared_ptr< IXmlElement > getRootElement() const override
Gets the root element of the document.
Definition PugiXmlImpl.h:140
void loadFromString(const std::vector< char > &xmlContent) override
Loads XML content from a vector of characters.
Definition PugiXmlImpl.h:133
Implementation of IXmlElement using PugiXML.
Definition PugiXmlImpl.h:69
std::shared_ptr< IXmlElement > getFirstChildElement(const std::string &tagName={}) const override
Finds the first child element.
Definition PugiXmlImpl.h:98
Element(::pugi::xml_node elem)
Constructor.
Definition PugiXmlImpl.h:80
std::string getTagName() const override
Gets the tag name of the element.
Definition PugiXmlImpl.h:82
std::string getText() const override
Gets the text content of the element.
Definition PugiXmlImpl.h:84
std::shared_ptr< IXmlAttribute > getFirstAttribute() const override
Gets the first attribute.
Definition PugiXmlImpl.h:88
std::shared_ptr< IXmlElement > getParent() const override
Gets the parent element.
Definition PugiXmlImpl.h:113
std::shared_ptr< IXmlElement > getPreviousSibling(const std::string &tagName={}) const override
Gets the previous sibling element.
Definition PugiXmlImpl.h:108
std::shared_ptr< IXmlElement > getNextSibling(const std::string &tagName={}) const override
Gets the next sibling element.
Definition PugiXmlImpl.h:103
std::shared_ptr< IXmlAttribute > findAttribute(const std::string &name) const override
Finds the first attribute.
Definition PugiXmlImpl.h:93
object model for musx file (enigmaxml)
Definition BaseClasses.h:32