From b8b1566f07600e8abac7d4c7770034e228c6d35d Mon Sep 17 00:00:00 2001 From: Peter M. Groen Date: Tue, 26 Jul 2022 01:35:21 +0200 Subject: [PATCH] Finished setting up code.. --- CMakeLists.txt | 3 +++ src/xmlbase.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- src/xmlbase.h | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- 3 files changed, 195 insertions(+), 63 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed82044..9604b32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,9 @@ LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake) include(projectheader) project_header(osdev_xml) +# First we build all the artifacts / dependencies +add_subdirectory(submodules/logger) + add_subdirectory(src) #add_subdirectory(test) #add_subdirectory(examples) diff --git a/src/xmlbase.cpp b/src/xmlbase.cpp index 8aa81fa..270ba5b 100644 --- a/src/xmlbase.cpp +++ b/src/xmlbase.cpp @@ -1,4 +1,26 @@ -#include "dcxmlbase.h" +/* **************************************************************************** + * Copyright 2019 Open Systems Development BV * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the "Software"), * + * to deal in the Software without restriction, including without limitation * + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * + * and/or sell copies of the Software, and to permit persons to whom the * + * Software is furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included in * + * all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * + * DEALINGS IN THE SOFTWARE. * + * ***************************************************************************/ + +#include "xmlbase.h" #include "log.h" /* @@ -27,24 +49,24 @@ void xml_string_writer::write(const void* data, size_t size) result += std::string(static_cast(data), size); } -DcXmlBase::DcXmlBase(const QString& xmlFile) +XmlBase::XmlBase(const QString& xmlFile) : m_xmldoc() , m_xPathHash() { if (!xmlFile.isNull() || !xmlFile.isEmpty()) { if (parseFile(xmlFile)) { - LogDebug("[DcXmlBase::DcXmlBase]", QString("File : %1 ..............[OK].").arg(xmlFile).toStdString()); + LogDebug("[XmlBase::XmlBase]", QString("File : %1 ..............[OK].").arg(xmlFile).toStdString()); } else { - LogError("[DcXmlBase::DcXmlBase]", QString("File : %1 ..............[Failed].").arg(xmlFile).toStdString()); - throw std::runtime_error("[DcXmlBase::DcXmlBase] parseFile failed"); + LogError("[XmlBase::XmlBase]", QString("File : %1 ..............[Failed].").arg(xmlFile).toStdString()); + throw std::runtime_error("[XmlBase::XmlBase] parseFile failed"); } } } -DcXmlBase::~DcXmlBase() = default; +XmlBase::~XmlBase() = default; -bool DcXmlBase::parseString(const QString& qsXml) +bool XmlBase::parseString(const QString& qsXml) { bool bResult = false; @@ -58,7 +80,7 @@ bool DcXmlBase::parseString(const QString& qsXml) return bResult; } -bool DcXmlBase::parseFile(const QString& qsXml) +bool XmlBase::parseFile(const QString& qsXml) { bool bResult = false; @@ -70,7 +92,7 @@ bool DcXmlBase::parseFile(const QString& qsXml) return bResult; } -bool DcXmlBase::checkError(pugi::xml_parse_status _parseStatus) +bool XmlBase::checkError(pugi::xml_parse_status _parseStatus) { bool bResult = false; QString sLogMessage = "An unknown error occured."; @@ -134,47 +156,48 @@ bool DcXmlBase::checkError(pugi::xml_parse_status _parseStatus) // case pugi::status_no_document_element: } #pragma GCC diagnostic pop - LogDebug("[DcXmlBase::checkError]", sLogMessage.toStdString()); + LogDebug("[XmlBase::checkError]", sLogMessage.toStdString()); return bResult; } -void DcXmlBase::addXPath(const QString& qsName, const QString& qsXPath) +void XmlBase::addXPath(const QString& qsName, const QString& qsXPath) { if (m_xPathHash.contains(qsName)) { - LogWarning("[DcXmlBase::addXPath]", std::string( "XPath already registered : " + qsName.toStdString())); + LogWarning("[XmlBase::addXPath]", QString( "XPath already registered : " + qsName).toStdString()); } m_xPathHash.insert(qsName, qsXPath); - LogDebug("[DcXmlBase::addXPath]", std::string("XPath" + qsXPath.toStdString() + " registered with key : " + qsName.toStdString())); + LogDebug("[XmlBase::addXPath]", QString("XPath" + qsXPath + " registered with key : " + qsName).toStdString()); } -QString DcXmlBase::getXPath(const QString& qsXPathSelect) const +QString XmlBase::getXPath(const QString& qsXPathSelect) const { QString qsXPath = m_xPathHash.value(qsXPathSelect); if (qsXPath.isEmpty()) { - LogWarning("dcxml", "XPath not registered : " + qsXPathSelect); + LogWarning("[XmlBase::getXPath]", QString("XPath not registered : " + qsXPathSelect).toStdString()); } return qsXPath; } -QString DcXmlBase::evaluateXPath(const QString& qsXPathSelect, +QString XmlBase::evaluateXPath(const QString& qsXPathSelect, const QList& arguments) const { QString qsResult = getXPath(qsXPathSelect); - // LogInfo( "DcXmlBase::evaluateXPath", QString( "Found XPathExpression : " + qsResult + " for selection : " + qsXPathSelect ) ); + LogDebug( "[XmlBase::evaluateXPath]", QString( "Found XPathExpression : " + qsResult + " for selection : " + qsXPathSelect ).toStdString() ); - for (auto& value : arguments) { + for (auto& value : arguments) + { qsResult = qsResult.arg(value.toString()); } - // LogInfo( "DcXmlBase::evaluateXPath", QString( "Resulting XPathExpression : " + qsResult ) ); + LogInfo("[XmlBase::evaluateXPath]", QString("Resulting XPathExpression : " + qsResult).toStdString()); return qsResult; } -void DcXmlBase::setSimpleData(const QString& qsXPathSelect, +void XmlBase::setSimpleData(const QString& qsXPathSelect, const QList& arguments, const QVariant& data) { @@ -182,14 +205,14 @@ void DcXmlBase::setSimpleData(const QString& qsXPathSelect, setNodeData(qsXPath, data); } -void DcXmlBase::setSimpleData(const QString& qsXPathSelect, const QVariant& data) +void XmlBase::setSimpleData(const QString& qsXPathSelect, const QVariant& data) { QString qsXPath = getXPath(qsXPathSelect); setNodeData(qsXPath, data); } -QVariant DcXmlBase::getSimpleData(const QString& qsXPathSelect, +QVariant XmlBase::getSimpleData(const QString& qsXPathSelect, const QList& arguments) const { QString qsXPath = evaluateXPath(qsXPathSelect, arguments); @@ -200,7 +223,7 @@ QVariant DcXmlBase::getSimpleData(const QString& qsXPathSelect, } // static -bool DcXmlBase::getBoolean(const QVariant& value) +bool XmlBase::getBoolean(const QVariant& value) { bool b_result = false; @@ -220,7 +243,7 @@ bool DcXmlBase::getBoolean(const QVariant& value) } // static -QString DcXmlBase::getAttributeValue(const pugi::xml_node& xmlNode, const char* attributeName) +QString XmlBase::getAttributeValue(const pugi::xml_node& xmlNode, const char* attributeName) { const auto attr = xmlNode.attribute(attributeName); if (attr.empty()) { @@ -229,12 +252,12 @@ QString DcXmlBase::getAttributeValue(const pugi::xml_node& xmlNode, const char* return attr.value(); } -pugi::xpath_node DcXmlBase::selectNode(const QString& qsXPath) const +pugi::xpath_node XmlBase::selectNode(const QString& qsXPath) const { return m_xmldoc.select_node(qsXPath.toStdString().c_str()); } -QList DcXmlBase::selectNodes(const QString& qsXPath) const +QList XmlBase::selectNodes(const QString& qsXPath) const { QList lstResult; @@ -246,7 +269,7 @@ QList DcXmlBase::selectNodes(const QString& qsXPath) const return lstResult; } -void DcXmlBase::setNodeData(const QString& qsXPath, const QVariant& qsData) +void XmlBase::setNodeData(const QString& qsXPath, const QVariant& qsData) { pugi::xml_node selectedNode; selectedNode = selectNode(qsXPath).node(); @@ -255,13 +278,11 @@ void DcXmlBase::setNodeData(const QString& qsXPath, const QVariant& qsData) selectedNode.set_value(qsData.toString().toStdString().c_str()); } else { - LogError("dcxml", - QString("No node(s) found for XPath expression : '%1'") - .arg(qsXPath)); + LogError("[XmlBase::setNodeData]", QString("No node(s) found for XPath expression : '%1'").arg(qsXPath).toStdString()); } } -QVariant DcXmlBase::getNodeData(const QString& qsXPath) const +QVariant XmlBase::getNodeData(const QString& qsXPath) const { QVariant qvResult; pugi::xml_node selectedNode = selectNode(qsXPath).node(); @@ -271,7 +292,7 @@ QVariant DcXmlBase::getNodeData(const QString& qsXPath) const return qvResult; } -QString DcXmlBase::asString() const +QString XmlBase::asString() const { xml_string_writer writer; m_xmldoc.save(writer); diff --git a/src/xmlbase.h b/src/xmlbase.h index 99949fd..c37f8c2 100644 --- a/src/xmlbase.h +++ b/src/xmlbase.h @@ -1,5 +1,5 @@ /* **************************************************************************** - * Copyright 2022 Open Systems Development BV * + * Copyright 2019 Open Systems Development BV * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the "Software"), * @@ -19,23 +19,22 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * * DEALINGS IN THE SOFTWARE. * * ***************************************************************************/ - #pragma once #include #include -#include -#include + +#include namespace osdev { namespace components { namespace xml { /*! - * \brief xml_string_writer - * This struct is used to write a pugixml DOM document to a std::string. - * pugiXML is not able to do this on its own, but we use the possibility - * to dump an xml-document to std::cout. + * \brief xml_string_writer + * This struct is used to write a pugiXL DOM document to a std::string (QString) + * pugiXML is not able to this on its own, but we use the possibility to dump + * an XML-document to std::cout */ struct xml_string_writer : pugi::xml_writer { @@ -44,50 +43,159 @@ struct xml_string_writer : pugi::xml_writer }; /*! - * \brief The XmlBase class describes the base class for all xml related classes. - * The basic functionality is implemented here. This class is intrended to - * be inherited an d specialized and not to be used directly. ( Nothing bad - * will happen, just to make life easier. ) + * \brief The XmlBase class describes the base class for all xml related classes + * The basic functionality is implemented here. This class is intended to + * be inherited and specialized and not to be used directly. ( Nothing bad + * will happen, just to make life easier ) + */ +/* + * ________________________________________ + * / I'm serious about thinking through all \ + * | the possibilities before we settle on | + * | anything. All things have the | + * | advantages of their disadvantages, and | + * | vice versa. | + * | | + * | -- Larry Wall in | + * \ <199709032332.QAA21669@wall.org> / + * ---------------------------------------- + * \ + * \ + * .--. + * |o_o | + * |:_/ | + * // \ \ + * (| | ) + * /'\_ _/`\ + * \___)=(___/ */ + class XmlBase { public: /*! Default constructor */ - explicit XmlBase(const std::string xmlFile = std::string() ); + explicit XmlBase(const QString& xmlFile = QString()); virtual ~XmlBase(); /*! - * \brief Parses the xml contents of the string. - * \param sxml - String containing the xml-string - * \return true if succesful, false if not... + * \brief Parses the XML contents of the string. + * \param qsXml - String containing the contents of the XML-string + * \return true if successfull, false if not... */ - bool parseString(const std::string &sxml); + bool parseString(const QString& qsXml); /*! - * \brief Parses the contents of the givenm XML-file. - * \param sxml - String with the filepath & -name of the xml file. - * \return true if succesfull, false if not. + * \brief Parses the contents of the given XML-file. + * \param qsXml - String with the filepath & -name of the XML file. + * \return true if successfull, false if not... */ - bool parseFile(const std::string sxml); + bool parseFile(const QString& qsXml); /*! - * \brief Adds and XPath expression to the internal structure. - * \param sName - Name of the XPath expression. This should be descriptive to make life easier. - * \param sXPath - The XPath expression to the specific data we're interested in. + * \brief Adds an XPath expression to the internal structure. + * \param qsName - Name of the XPath expression. This should be descriptive to make life easier + * \param qsXPath - The XPath expression to the specific data we're interested in. */ - void addXPath(const std::string &sName, const std::string &sXPath); + void addXPath(const QString& qsName, const QString& qsXPath); /*! - * \brief Retrieves an XPatrh expression from the internal structure - * \param sXpathSelect - The name of the XPath expression - * \return The XPath expression as stored in the internal Hash. + * \brief Retrieves an XPath expression from the internal structure + * \param qsXPathSelect - The name of the XPath expression. + * \return The XPath expression as stored in the internal Hash */ - std::string getXPath(const std::string &sXpathSelect); + QString getXPath(const QString& qsXPathSelect) const; + /*! + * \brief Interprets the XPath expression and adds values to the variables. + * \param qsXPathSelect - The XPath expression as given by getXPath. + * \param arguments - The list of variables to be added to the XPath expression. + * \return The interpreted XPath expression. + */ + QString evaluateXPath(const QString& qsXPathSelect, const QList& arguments) const; -}; + /*! + * \brief Set a simple node in the xml-doc. + * \param qsXPathSelect - The XPath expression of the node we want to set. + * \param arguments - the list of arguments in the node + * \param data - The nodetext. + */ + void setSimpleData(const QString& qsXPathSelect, const QList& arguments, const QVariant& data); + /*! + * \brief Set a simple node in the xml-doc. + * \param qsXPathSelect - The XPath expression of the node we want to set. + * \param data - The nodetext. + */ + void setSimpleData(const QString& qsXPathSelect, const QVariant& data); + + QVariant getSimpleData(const QString& qsXPathSelect, const QList& arguments) const; + + /*! + * \brief Retreive a single node based on the XPath expression + * \param qsXPath - The XPath expression + * \return - a single xpath-node + */ + pugi::xpath_node selectNode(const QString& qsXPath) const; + + /*! + * \brief Retreives a list of nodes based on the given XPath expression + * \param qsXPath - The XPath expression + * \return - The list of nodes + */ + QList selectNodes(const QString& qsXPath) const; + + /*! Added for convenience. The DOMTree is exported as QString */ + QString asString() const; + + /*! Helper method for the setSimpleData */ + void setNodeData(const QString& qsXPath, const QVariant& qsData); + + //! Helper method for the getSimpleData. Get data from the node that + //! is selected with the XPath expression. + virtual QVariant getNodeData(const QString& qsXPath) const; + + /** + * @brief Turns a value into a boolean. + * @param value Value to be interpreted. + * @return boolean representation of value + * + * The following (capitalised) items convert to "true" : + * - Y + * - YES + * - TRUE + * - ON + * - 1 + * + * Everything else converts to false. + */ + static bool getBoolean(const QVariant& value); + + /** + * @param xmlNode The node to query for an attribute value. + * @param attributeName The name of the attribute to query. + * @return an attribute value. + * @retval value as QString + * @retval null QString when the attribute is not found. + */ + static QString getAttributeValue(const pugi::xml_node& xmlNode, const char* attributeName); + +private: + /*! + * \brief Translates the pugiXML status into Human Readable messages + * \param parseStatus - The pugi::XML status enum from the parser. + * \return True if there was no error whatsoever. False if not.. 8-| + */ + bool checkError(pugi::xml_parse_status parseStatus); + + /*! + * \brief The internal representation of the XML document. + */ + pugi::xml_document m_xmldoc; + + //! Storage for the XPath expressions + QHash m_xPathHash; +}; } // End namespace xml -} // End namespace components } // End namespace osdev +} // End namespace components -- libgit2 0.21.4