xml_element.hpp
Go to the documentation of this file.
1 #ifndef RADIAL_MENU_MODEL_XML_ELEMENT_HPP
2 #define RADIAL_MENU_MODEL_XML_ELEMENT_HPP
3 
4 #include <memory>
5 #include <sstream>
6 #include <string>
7 #include <vector>
8 
9 #include <ros/console.h>
10 
11 #include <boost/optional.hpp>
12 #include <boost/property_tree/exceptions.hpp>
13 #include <boost/property_tree/ptree.hpp>
14 #include <boost/property_tree/xml_parser.hpp>
15 
16 namespace radial_menu_model {
17 
18 class XmlElement;
19 typedef std::shared_ptr< XmlElement > XmlElementPtr;
20 typedef std::shared_ptr< const XmlElement > XmlElementConstPtr;
21 
22 class XmlElement {
23 protected:
24  XmlElement(const std::shared_ptr< const boost::property_tree::ptree > &xml,
25  const boost::property_tree::ptree::value_type *const elm)
26  : xml_(xml), elm_(elm) {}
27 
28 public:
29  virtual ~XmlElement() {}
30 
31  // element name
32  const std::string &name() const { return elm_->first; }
33 
34  // get an attribute like ros::param::param()
35  template < typename T > T attribute(const std::string &key, const T &default_val) const {
36  return elm_->second.get("<xmlattr>." + key, default_val);
37  }
38 
39  // get an attribute like ros::param::get()
40  template < typename T > bool getAttribute(const std::string &key, T *const val) const {
41  const boost::optional< T > opt_val(elm_->second.get_optional< T >("<xmlattr>." + key));
42  if (opt_val) {
43  *val = *opt_val;
44  return true;
45  }
46  return false;
47  }
48 
49  std::size_t numChildElements() const {
50  std::size_t n(0);
51  for (const boost::property_tree::ptree::value_type &child_elm : elm_->second) {
52  if (child_elm.first != "<xmlattr>") {
53  ++n;
54  }
55  }
56  return n;
57  }
58 
59  std::vector< XmlElementConstPtr > childElements() const {
60  std::vector< XmlElementConstPtr > elms;
61  for (const boost::property_tree::ptree::value_type &child_elm : elm_->second) {
62  if (child_elm.first != "<xmlattr>") {
63  elms.push_back(XmlElementConstPtr(new XmlElement(xml_, &child_elm)));
64  }
65  }
66  return elms;
67  }
68 
69  static XmlElementConstPtr fromString(const std::string &str) {
70  namespace bpt = boost::property_tree;
71 
72  // parse the given string as a xml
73  const std::shared_ptr< bpt::ptree > xml(new bpt::ptree());
74  try {
75  std::istringstream iss(str);
76  bpt::read_xml(iss, *xml, bpt::xml_parser::no_comments);
77  } catch (const bpt::ptree_error &ex) {
78  ROS_ERROR_STREAM("XmlElement::fromString(): " << ex.what());
79  return XmlElementConstPtr();
80  }
81 
82  // assert the xml has the unique root element
83  if (xml->empty()) {
84  ROS_ERROR("XmlElement::fromString(): No root element in xml");
85  return XmlElementConstPtr();
86  } else if (xml->size() >= 2) {
87  ROS_ERROR("XmlElement::fromString(): Multiple root elements in xml");
88  return XmlElementConstPtr();
89  }
90 
91  // return the root element
92  return XmlElementConstPtr(new XmlElement(xml, &xml->front()));
93  }
94 
95 protected:
96  const std::shared_ptr< const boost::property_tree::ptree > xml_;
97  const boost::property_tree::ptree::value_type *const elm_;
98 };
99 } // namespace radial_menu_model
100 
101 #endif
const std::shared_ptr< const boost::property_tree::ptree > xml_
Definition: xml_element.hpp:96
const boost::property_tree::ptree::value_type *const elm_
Definition: xml_element.hpp:97
static XmlElementConstPtr fromString(const std::string &str)
Definition: xml_element.hpp:69
bool getAttribute(const std::string &key, T *const val) const
Definition: xml_element.hpp:40
const std::string & name() const
Definition: xml_element.hpp:32
T attribute(const std::string &key, const T &default_val) const
Definition: xml_element.hpp:35
std::size_t numChildElements() const
Definition: xml_element.hpp:49
std::shared_ptr< XmlElement > XmlElementPtr
Definition: xml_element.hpp:18
XmlElement(const std::shared_ptr< const boost::property_tree::ptree > &xml, const boost::property_tree::ptree::value_type *const elm)
Definition: xml_element.hpp:24
std::vector< XmlElementConstPtr > childElements() const
Definition: xml_element.hpp:59
#define ROS_ERROR_STREAM(args)
#define ROS_ERROR(...)
std::shared_ptr< const XmlElement > XmlElementConstPtr
Definition: xml_element.hpp:20


radial_menu_model
Author(s):
autogenerated on Mon Feb 28 2022 23:22:00