8#include <unordered_map>
14#include <xercesc/dom/DOM.hpp>
52 operator std::string_view()
const {
return value; };
53 operator std::string()
const {
return value; };
55 operator int()
const {
try {
return std::stoi(
value); }
catch(...) {
throw std::runtime_error(
"Cannot convert '" +
value +
"' to int"); } };
56 operator double()
const {
try {
return std::stod(
value); }
catch(...) {
throw std::runtime_error(
"Cannot convert '" +
value +
"' to double"); } };
65 inline static std::string
True =
"true";
66 inline static std::string
False =
"false";
83typedef std::vector<std::unique_ptr<XMLObject>>
Children;
100template<
typename Self,
typename T>
101using like_const_t = std::conditional_t<std::is_const_v<std::remove_reference_t<Self>>,
const T, T>;
172 template<
typename T,
typename Self>
inline auto*
is(
this Self&& self) {
182 template<
typename T,
typename Self>
inline auto*
get(
this Self&& self) {
183 auto* ptr = self.template
is<T>();
184 if ( ptr ==
nullptr ) {
185 throw std::runtime_error(
"Failed to cast element '" + self.XMLObject::elementName +
"' from class '" + self.XMLObject::className +
"' to type '" +
typeid(T).name() +
"'");
194 void findRecursive(std::vector<std::reference_wrapper<T> >& result,
const Children& descendants)
const
196 for (
auto& descendant : descendants) {
197 if (
auto* ptr = descendant->template
is<T>()) {
198 result.push_back(*ptr);
200 findRecursive(result, descendant->children );
211 template<
typename T,
typename Self>
214 std::vector<std::reference_wrapper<like_const_t<Self, T> > > result;
215 self.findRecursive(result, self.XMLObject::children);
241 std::string
format(std::string indentation =
"\t",
unsigned int depth = 0)
const;
251 for (
auto& child : self.XMLObject::children ) {
256 throw std::runtime_error(
"Failed to find required child of type '" + std::string(
typeid(T).name()) +
"' in element '" + self.XMLObject::elementName +
"'");
268 for (
auto& child : self.XMLObject::children ) {
269 if (
auto* ptr = child->template
is<E>() ) {
270 return std::optional< std::reference_wrapper<E> >(*ptr);
273 return std::optional< std::reference_wrapper<E> >(std::nullopt);
283 template<
typename T,
typename Self>
auto getChildren(
this Self&& self) {
285 std::vector< std::reference_wrapper<E> > result;
286 for (
auto& child : self.XMLObject::children ) {
287 if (
auto* ptr = child->template
is<E>() ) {
288 result.push_back(*ptr);
303 for (
auto& child : self.XMLObject::children ) {
304 if ( child->elementName == name ) {
308 throw std::runtime_error(
"Failed to get required child '" + name +
"' of element '" + self.XMLObject::elementName +
"'");
321 for (
auto& child : self.XMLObject::children ) {
322 if ( child->elementName == name ) {
323 return std::optional< std::reference_wrapper<O> >(
static_cast<O&
>(*child));
326 return std::optional< std::reference_wrapper<O> >(std::nullopt);
339 std::vector< std::reference_wrapper<O> > result;
340 for (
auto& child : self.XMLObject::children ) {
341 if ( child->elementName == name ) {
342 result.push_back(
static_cast<O&
>(*child));
357 for (
auto& attribute : self.XMLObject::attributes ) {
358 if ( attribute.name == name ) {
362 throw std::runtime_error(
"Failed to get required attribute '" + name +
"' of element '" + self.XMLObject::elementName +
"'");
375 for (
auto& attribute : self.XMLObject::attributes ) {
376 if ( attribute.name == name ) {
377 return std::optional< std::reference_wrapper<A> >(attribute);
380 return std::optional< std::reference_wrapper<A> >(std::nullopt);
387std::ostream&
operator<<(std::ostream& os,
const XMLObject* obj);
389std::ostream&
operator<<(std::ostream& os,
const XMLObject& obj);
A class representing a node in an XML-tree.
auto getOptionalChild(this Self &&self)
Get an optional child of type T.
auto * get(this Self &&self)
Attempt to cast the current instance to the specified type T.
static XMLObject * createFromFile(const std::string &filename)
Create an XMLObject from an XML file.
static XMLObject * createFromString(const std::string &xmlString)
Create an XMLObject from a string representation of XML.
static XMLObject * createObject(const xercesc::DOMElement *element)
auto & getRequiredChild(this Self &&self)
Get a required child of type T.
const ClassName className
auto & getRequiredChildByName(this Self &&self, const ElementName &name)
Get a required child with the specified element name.
auto getChildren(this Self &&self)
Get all children of type T.
auto getOptionalAttributeByName(this Self &&self, const AttributeName &name)
Get an optional attribute with the specified attribute name.
std::string format(std::string indentation="\t", unsigned int depth=0) const
Creates formatted string representing the XMLObject including its children.
Children children
Child nodes of the XML element.
auto getChildrenByName(this Self &&self, const ElementName &name)
Get all children with the specified element name.
auto & getRequiredAttributeByName(this Self &&self, const AttributeName &name)
Get a required attribute with the specified attribute name.
TextContent textContent
Textual content of XML element without children.
std::string stringify() const
Convert the XMLObject and its children to a string representation.
XMLObject(const Namespace &xmlns, const ClassName &className, const xercesc::DOMElement *element, const Attributes &defaultAttributes)
friend XMLObject * createInstance(const Namespace &xmlns, const ClassName &className, const xercesc::DOMElement *element)
Template function used to store in factory.
auto find(this Self &&self)
Find all descendants of type T.
static XMLObject * createFromStream(std::istream &xmlStream)
Create an XMLObject from the input stream.
static const Attributes defaults
Attributes of the XML element.
auto getOptionalChildByName(this Self &&self, const ElementName &name)
Get the optional child with the specified element name.
auto * is(this Self &&self)
Returns a pointer of type T of the object, const-qualified to match the receiver.
The XML namespace contains classes representing XML-nodes defined in given XML-schema(s).
std::ostream & operator<<(std::ostream &os, const XMLObject *obj)
Allows printing of stringified XML object.
std::vector< Attribute > Attributes
std::vector< std::unique_ptr< XMLObject > > Children
XMLObject * createInstance(const Namespace &xmlns, const ClassName &className, const xercesc::DOMElement *element)
Template function used to store in factory.
std::unordered_map< ElementName, XMLObject *(*)(const Namespace &xmlns, const ClassName &className, const xercesc::DOMElement *element)> Factory
Factory used to create instance depending on element name.
std::conditional_t< std::is_const_v< std::remove_reference_t< Self > >, const T, T > like_const_t
Yields const T when the deduced Self is a const-qualified object, otherwise T.
std::string AttributeName
A struct representing an attribute of an XML-node.
A struct representing the value of an XML-node attribute.
Value(const std::string &s)
Value & operator=(bool b)
Value & operator=(double d)
Value & operator=(const std::string &s)