/* **************************************************************************** * Copyright 2022 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. * * ***************************************************************************/ #pragma once #include #include #include namespace osdev { namespace components { namespace xml { /*! * \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 { std::string result = std::string(); virtual void write(const void* data, size_t size) override; }; /*! * \brief The dcXmlBase 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 DcXmlBase { public: /*! Default constructor */ explicit DcXmlBase(const QString& xmlFile = QString()); virtual ~DcXmlBase(); /*! * \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 QString& qsXml); /*! * \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 QString& qsXml); /*! * \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 QString& qsName, const QString& qsXPath); /*! * \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 */ 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 osdev } // End namespace components