diff --git a/lib/XmlReader.cpp b/lib/XmlReader.cpp index 735adb1..5a6eb3e 100644 --- a/lib/XmlReader.cpp +++ b/lib/XmlReader.cpp @@ -54,3 +54,16 @@ void XmlReader::open(const std::string &fileName) } root_ = doc_.RootElement(); } + +// XML structure access //////////////////////////////////////////////////////// +const XmlNode * XmlReader::getNextNode(const XmlNode *node) +{ + if (node) + { + return node->NextSiblingElement(); + } + else + { + return nullptr; + } +} diff --git a/lib/XmlReader.hpp b/lib/XmlReader.hpp index 4027dbc..ddc026a 100644 --- a/lib/XmlReader.hpp +++ b/lib/XmlReader.hpp @@ -30,6 +30,8 @@ BEGIN_NAMESPACE /****************************************************************************** * XML parameter file reader * ******************************************************************************/ +typedef tinyxml2::XMLElement XmlNode; + class XmlReader { public: @@ -39,76 +41,57 @@ public: // destructor virtual ~XmlReader(void) = default; // IO - template - T getFirstValue(const std::string &nodeName, Strs... nodeNames); - template - std::vector getAllValues(const std::string &nodeName, Strs... nodeNames); void open(const std::string &fileName); -private: + // XML structure access template - tinyxml2::XMLElement * getFirstNode(const std::string &nodeName, + static const XmlNode * getFirstNode(const XmlNode *startNode, + const std::string &nodeName, Strs... nodeNames); + template + const XmlNode * getFirstNode(const std::string &nodeName, + Strs... nodeNames) const; + static const XmlNode * getNextNode(const XmlNode *node); + template + static T getValue(const XmlNode *node); + template + static T getFirstValue(const XmlNode *startNode, + const std::string &nodeName, Strs... nodeNames); + template + T getFirstValue(const std::string &nodeName, Strs... nodeNames) const; + template + static std::vector getAllValues(const XmlNode *startNode, + const std::string &nodeName, + Strs... nodeNames); + template + std::vector getAllValues(const std::string &nodeName, + Strs... nodeNames) const; +private: + private: std::string name_; tinyxml2::XMLDocument doc_; - tinyxml2::XMLElement *root_{nullptr}; + XmlNode *root_{nullptr}; }; /****************************************************************************** * XmlReader template implementation * ******************************************************************************/ -template -T XmlReader::getFirstValue(const std::string &nodeName, Strs... nodeNames) -{ - tinyxml2::XMLElement *node = getFirstNode(nodeName, nodeNames...); - - if (node->GetText()) - { - return strTo(node->GetText()); - } - else - { - return T(); - } -} - -template -std::vector XmlReader::getAllValues(const std::string &nodeName, - Strs... nodeNames) -{ - tinyxml2::XMLElement *node = getFirstNode(nodeName, nodeNames...); - std::vector value; - - while (node) - { - if (node->GetText()) - { - value.push_back(strTo(node->GetText())); - } - else - { - value.push_back(T()); - } - node = node->NextSiblingElement(); - } - - return value; -} - +// XML structure access //////////////////////////////////////////////////////// template -tinyxml2::XMLElement * XmlReader::getFirstNode(const std::string &nodeName, - Strs... nodeNames) +const XmlNode * XmlReader::getFirstNode(const XmlNode *startNode, + const std::string &nodeName, + Strs... nodeNames) { static_assert(static_or::value...>::value, "getFirstValue arguments are not compatible with std::string"); - const unsigned int nName = sizeof...(nodeNames) + 1; - const std::string name[] = {nodeName, nodeNames...}; - tinyxml2::XMLElement *node = root_; + const unsigned int nName = sizeof...(nodeNames) + 1; + const std::string name[] = {nodeName, nodeNames...}; + const XmlNode *node = startNode; - if (!root_) + if (!node) { - LATAN_ERROR(Io, "no XML file opened"); + LATAN_ERROR(Io, "root node is null, no XML file opened"); } for (unsigned int i = 0; i < nName; ++i) { @@ -122,6 +105,77 @@ tinyxml2::XMLElement * XmlReader::getFirstNode(const std::string &nodeName, return node; } +template +const XmlNode * XmlReader::getFirstNode(const std::string &nodeName, + Strs... nodeNames) const +{ + if (!root_) + { + LATAN_ERROR(Io, "root node is null, no XML file opened"); + } + + return getFirstNode(root_, nodeName, nodeNames...); +} + +template +T XmlReader::getValue(const XmlNode *node) +{ + if (node) + { + if (node->GetText()) + { + return strTo(node->GetText()); + } + else + { + return T(); + } + } + else + { + return T(); + } +} + +template +T XmlReader::getFirstValue(const XmlNode *startNode, + const std::string &nodeName, Strs... nodeNames) +{ + const XmlNode *node = getFirstNode(startNode, nodeName, nodeNames...); + + return getValue(node); +} + +template +T XmlReader::getFirstValue(const std::string &nodeName, Strs... nodeNames) const +{ + return getFirstValue(root_, nodeName, nodeNames...); +} + +template +std::vector XmlReader::getAllValues(const XmlNode *startNode, + const std::string &nodeName, + Strs... nodeNames) +{ + const XmlNode *node = getFirstNode(startNode, nodeName, nodeNames...); + std::vector value; + + while (node) + { + value.push_back(getValue(node)); + node = getNextNode(node); + } + + return value; +} + +template +std::vector XmlReader::getAllValues(const std::string &nodeName, + Strs... nodeNames) const +{ + return getAllValues(root_, nodeName, nodeNames...); +} + END_NAMESPACE #endif // Latan_XmlReader_hpp_