Warning, file /office/calligra/libs/store/KoXmlReader.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002    Copyright (C) 2005-2006 Ariya Hidayat <ariya@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KO_XMLREADER_H
0021 #define KO_XMLREADER_H
0022 
0023 // KOXML_USE_QDOM is defined there
0024 #include "KoXmlReaderForward.h"
0025 
0026 #include "kostore_export.h"
0027 
0028 #include <QPair>
0029 #include <QtXml>
0030 #include <QDomDocument>
0031 
0032 class QIODevice;
0033 
0034 #ifdef KOXML_USE_QDOM
0035 
0036 typedef QDomNode KoXmlNode;
0037 typedef QDomElement KoXmlElement;
0038 typedef QDomText KoXmlText;
0039 typedef QDomCDATASection KoXmlCDATASection;
0040 typedef QDomDocumentType KoXmlDocumentType;
0041 typedef QDomDocument KoXmlDocument;
0042 
0043 #else
0044 
0045 class QString;
0046 class QXmlStreamReader;
0047 
0048 class KoXmlNode;
0049 class KoXmlText;
0050 class KoXmlCDATASection;
0051 class KoXmlDocumentType;
0052 class KoXmlDocument;
0053 class KoXmlNodeData;
0054 class KoXmlDocumentData;
0055 
0056 /**
0057  * The office-text-content-prelude type.
0058  */
0059 enum KoXmlNamedItemType {
0060     KoXmlTextContentPrelude ///< office-text-content-prelude
0061     //KoXmlTextContentMain, ///< office-text-content-main
0062     //KoXmlTextContentEpilogue ///< office-text-content-epilogue
0063 };
0064 
0065 /**
0066 * KoXmlNode represents a node in a DOM tree.
0067 *
0068 * KoXmlNode is a base class for KoXmlElement, KoXmlText.
0069 * Often, these subclasses are used for getting the data instead of KoXmlNode.
0070 * However, as base class, KoXmlNode is very helpful when for example iterating
0071 * all child nodes within one parent node.
0072 *
0073 * KoXmlNode implements an explicit sharing, a node shares its data with
0074 * other copies (if exist).
0075 *
0076 * XXX: DO NOT ADD CONVENIENCE API HERE BECAUSE THIS CLASS MUST REMAIN COMPATIBLE WITH QDOMNODE!
0077 *
0078 * @author Ariya Hidayat <ariya@kde.org>
0079 */
0080 class KOSTORE_EXPORT KoXmlNode
0081 {
0082 public:
0083 
0084     enum NodeType {
0085         NullNode = 0,
0086         ElementNode,
0087         TextNode,
0088         CDATASectionNode,
0089         ProcessingInstructionNode,
0090         DocumentNode,
0091         DocumentTypeNode
0092     };
0093 
0094     KoXmlNode();
0095     KoXmlNode(const KoXmlNode& node);
0096     KoXmlNode& operator=(const KoXmlNode& node);
0097     bool operator== (const KoXmlNode&) const;
0098     bool operator!= (const KoXmlNode&) const;
0099     virtual ~KoXmlNode();
0100 
0101     virtual KoXmlNode::NodeType nodeType() const;
0102     virtual bool isNull() const;
0103     virtual bool isElement() const;
0104     virtual bool isText() const;
0105     virtual bool isCDATASection() const;
0106     virtual bool isDocument() const;
0107     virtual bool isDocumentType() const;
0108 
0109     virtual void clear();
0110     KoXmlElement toElement() const;
0111     KoXmlText toText() const;
0112     KoXmlCDATASection toCDATASection() const;
0113     KoXmlDocument toDocument() const;
0114 
0115     virtual QString nodeName() const;
0116     virtual QString namespaceURI() const;
0117     virtual QString prefix() const;
0118     virtual QString localName() const;
0119 
0120     KoXmlDocument ownerDocument() const;
0121     KoXmlNode parentNode() const;
0122 
0123     bool hasChildNodes() const;
0124     KoXmlNode firstChild() const;
0125     KoXmlNode lastChild() const;
0126     KoXmlNode nextSibling() const;
0127     KoXmlNode previousSibling() const;
0128 
0129     KoXmlElement firstChildElement() const;
0130 
0131     // equivalent to node.childNodes().count() if node is a QDomNode instance
0132     int childNodesCount() const;
0133 
0134     // workaround to get and iterate over all attributes
0135     QStringList attributeNames() const;
0136     QList< QPair<QString, QString> > attributeFullNames() const;
0137 
0138     KoXmlNode namedItem(const QString& name) const;
0139     KoXmlNode namedItemNS(const QString& nsURI, const QString& name) const;
0140     KoXmlNode namedItemNS(const QString& nsURI, const QString& name, KoXmlNamedItemType type) const;
0141 
0142     /**
0143     * Loads all child nodes (if any) of this node. Normally you do not need
0144     * to call this function as the child nodes will be automatically
0145     * loaded when necessary.
0146     */
0147     void load(int depth = 1);
0148 
0149     /**
0150     * Releases all child nodes of this node.
0151     */
0152     void unload();
0153 
0154     // compatibility
0155     /**
0156      * @internal do not call directly
0157      * Use KoXml::asQDomDocument(), KoXml::asQDomElement() or KoXml::asQDomNode() instead
0158      */
0159     void asQDomNode(QDomDocument& ownerDoc) const;
0160 
0161 protected:
0162     KoXmlNodeData* d;
0163     explicit KoXmlNode(KoXmlNodeData*);
0164 };
0165 
0166 /**
0167 * KoXmlElement represents a tag element in a DOM tree.
0168 *
0169 * KoXmlElement holds information about an XML tag, along with its attributes.
0170 *
0171 * @author Ariya Hidayat <ariya@kde.org>
0172 */
0173 
0174 class KOSTORE_EXPORT KoXmlElement: public KoXmlNode
0175 {
0176 public:
0177     KoXmlElement();
0178     KoXmlElement(const KoXmlElement& element);
0179     KoXmlElement& operator=(const KoXmlElement& element);
0180     ~KoXmlElement() override;
0181     bool operator== (const KoXmlElement&) const;
0182     bool operator!= (const KoXmlElement&) const;
0183 
0184     QString tagName() const;
0185     QString text() const;
0186 
0187     QString attribute(const QString& name) const;
0188     QString attribute(const QString& name, const QString& defaultValue) const;
0189     QString attributeNS(const QString& namespaceURI, const QString& localName,
0190                         const QString& defaultValue = QString()) const;
0191     bool hasAttribute(const QString& name) const;
0192     bool hasAttributeNS(const QString& namespaceURI, const QString& localName) const;
0193 
0194 private:
0195     friend class KoXmlNode;
0196     friend class KoXmlDocument;
0197     explicit KoXmlElement(KoXmlNodeData*);
0198 };
0199 
0200 /**
0201 * KoXmlText represents a text in a DOM tree.
0202 * @author Ariya Hidayat <ariya@kde.org>
0203 */
0204 class KOSTORE_EXPORT KoXmlText: public KoXmlNode
0205 {
0206 public:
0207     KoXmlText();
0208     KoXmlText(const KoXmlText& text);
0209     KoXmlText& operator=(const KoXmlText& text);
0210     ~KoXmlText() override;
0211 
0212     QString data() const;
0213     bool isText() const override;
0214 
0215 private:
0216     friend class KoXmlNode;
0217     friend class KoXmlCDATASection;
0218     friend class KoXmlDocument;
0219     explicit KoXmlText(KoXmlNodeData*);
0220 };
0221 
0222 /**
0223 * KoXmlCDATASection represents a CDATA section in a DOM tree.
0224 * @author Ariya Hidayat <ariya@kde.org>
0225 */
0226 class KOSTORE_EXPORT KoXmlCDATASection: public KoXmlText
0227 {
0228 public:
0229     KoXmlCDATASection();
0230     KoXmlCDATASection(const KoXmlCDATASection& cdata);
0231     KoXmlCDATASection& operator=(const KoXmlCDATASection& cdata);
0232     ~KoXmlCDATASection() override;
0233 
0234     bool isCDATASection() const override;
0235 
0236 private:
0237     friend class KoXmlNode;
0238     friend class KoXmlDocument;
0239     explicit KoXmlCDATASection(KoXmlNodeData*);
0240 };
0241 
0242 /**
0243 * KoXmlDocumentType represents the DTD of the document. At the moment,
0244 * it can used only to get the document type, i.e. no support for
0245 * entities etc.
0246 *
0247 * @author Ariya Hidayat <ariya@kde.org>
0248 */
0249 
0250 class KOSTORE_EXPORT KoXmlDocumentType: public KoXmlNode
0251 {
0252 public:
0253     KoXmlDocumentType();
0254     KoXmlDocumentType(const KoXmlDocumentType&);
0255     KoXmlDocumentType& operator=(const KoXmlDocumentType&);
0256     ~KoXmlDocumentType() override;
0257 
0258     QString name() const;
0259 
0260 private:
0261     friend class KoXmlNode;
0262     friend class KoXmlDocument;
0263     friend class KoXmlDocumentData;
0264     explicit KoXmlDocumentType(KoXmlNodeData*);
0265 };
0266 
0267 
0268 /**
0269 * KoXmlDocument represents an XML document, structured in a DOM tree.
0270 *
0271 * KoXmlDocument is designed to be memory efficient. Unlike QDomDocument from
0272 * Qt's XML module, KoXmlDocument does not store all nodes in the DOM tree.
0273 * Some nodes will be loaded and parsed on-demand only.
0274 *
0275 * KoXmlDocument is read-only, you can not modify its content.
0276 *
0277 * @author Ariya Hidayat <ariya@kde.org>
0278 */
0279 
0280 class KOSTORE_EXPORT KoXmlDocument: public KoXmlNode
0281 {
0282 public:
0283     explicit KoXmlDocument(bool stripSpaces = false);
0284     KoXmlDocument(const KoXmlDocument& node);
0285     KoXmlDocument& operator=(const KoXmlDocument& node);
0286     bool operator==(const KoXmlDocument&) const;
0287     bool operator!=(const KoXmlDocument&) const;
0288     ~KoXmlDocument() override;
0289 
0290     KoXmlElement documentElement() const;
0291 
0292     KoXmlDocumentType doctype() const;
0293 
0294     QString nodeName() const override;
0295     void clear() override;
0296 
0297     bool setContent(QIODevice* device, bool namespaceProcessing,
0298                     QString* errorMsg = 0, int* errorLine = 0, int* errorColumn = 0);
0299     bool setContent(QIODevice* device,
0300                     QString* errorMsg = 0, int* errorLine = 0, int* errorColumn = 0);
0301     bool setContent(QXmlStreamReader *reader,
0302                     QString* errorMsg = 0, int* errorLine = 0, int* errorColumn = 0);
0303     bool setContent(const QByteArray& text, bool namespaceProcessing,
0304                     QString *errorMsg = 0, int *errorLine = 0, int *errorColumn = 0);
0305     bool setContent(const QString& text, bool namespaceProcessing,
0306                     QString *errorMsg = 0, int *errorLine = 0, int *errorColumn = 0);
0307 
0308     // no namespace processing
0309     bool setContent(const QString& text,
0310                     QString *errorMsg = 0, int *errorLine = 0, int *errorColumn = 0);
0311      /**
0312      * Change the way an XMLDocument will be read:
0313      * if stripSpaces = true then a will only have one child
0314      * if stripSpaces = false then a will have 3 children.
0315      */
0316     void setWhitespaceStripping(bool stripSpaces);
0317 
0318 private:
0319     friend class KoXmlNode;
0320     explicit KoXmlDocument(KoXmlDocumentData*);
0321 };
0322 
0323 #endif // KOXML_USE_QDOM
0324 
0325 /**
0326  * This namespace contains a few convenience functions to simplify code using QDom
0327  * (when loading OASIS documents, in particular).
0328  *
0329  * To find the child element with a given name, use KoXml::namedItemNS.
0330  *
0331  * To find all child elements with a given name, use
0332  * QDomElement e;
0333  * forEachElement( e, parent )
0334  * {
0335  *     if ( e.localName() == "..." && e.namespaceURI() == KoXmlNS::... )
0336  *     {
0337  *         ...
0338  *     }
0339  * }
0340  * Note that this means you don't ever need to use QDomNode nor toElement anymore!
0341  * Also note that localName is the part without the prefix, this is the whole point
0342  * of namespace-aware methods.
0343  *
0344  * To find the attribute with a given name, use QDomElement::attributeNS.
0345  *
0346  * Do not use getElementsByTagNameNS, it's recursive (which is never needed in Calligra).
0347  * Do not use tagName() or nodeName() or prefix(), since the prefix isn't fixed.
0348  *
0349  * @author David Faure <faure@kde.org>
0350  */
0351 namespace KoXml
0352 {
0353 
0354 /**
0355  * A namespace-aware version of QDomNode::namedItem(),
0356  * which also takes care of casting to a QDomElement.
0357  *
0358  * Use this when a domelement is known to have only *one* child element
0359  * with a given tagname.
0360  *
0361  * Note: do *NOT* use getElementsByTagNameNS, it's recursive!
0362  */
0363 KOSTORE_EXPORT KoXmlElement namedItemNS(const KoXmlNode& node,
0364                                         const QString& nsURI, const QString& localName);
0365 
0366 /**
0367  * A namespace-aware version of QDomNode::namedItem().
0368  * which also takes care of casting to a QDomElement.
0369  *
0370  * Use this when you like to return the first or an invalid
0371  * KoXmlElement with a known type.
0372  *
0373  * This is an optimized version of the namedItemNS above to
0374  * give fast access to certain sections of the document using
0375  * the office-text-content-prelude condition as @a KoXmlNamedItemType .
0376  */
0377 KOSTORE_EXPORT KoXmlElement namedItemNS(const KoXmlNode& node,
0378                                       const QString& nsURI, const QString& localName,
0379                                       KoXmlNamedItemType type);
0380 
0381 /**
0382  * Explicitly load child nodes of specified node, up to given depth.
0383  * This function has no effect if QDom is used.
0384  */
0385 KOSTORE_EXPORT void load(KoXmlNode& node, int depth = 1);
0386 
0387 /**
0388  * Unload child nodes of specified node.
0389  * This function has no effect if QDom is used.
0390  */
0391 KOSTORE_EXPORT void unload(KoXmlNode& node);
0392 
0393 /**
0394  * Get the number of child nodes of specified node.
0395  */
0396 KOSTORE_EXPORT int childNodesCount(const KoXmlNode& node);
0397 
0398 /**
0399  * Return the name of all attributes of specified node.
0400  */
0401 KOSTORE_EXPORT QStringList attributeNames(const KoXmlNode& node);
0402 
0403 /**
0404  * Convert KoXmlNode classes to the corresponding QDom classes, which has
0405  * @p ownerDoc as the owner document (QDomDocument instance).
0406  * The converted @p node (and its children) are added to ownerDoc.
0407  *
0408  * NOTE:
0409  * - If ownerDoc is not empty, this may fail, @see QDomDocument
0410  * - @p node must not be a KoXmlDocument, use asQDomDocument()
0411  * 
0412  * @see asQDomDocument, asQDomElement
0413  */
0414 KOSTORE_EXPORT void asQDomNode(QDomDocument& ownerDoc, const KoXmlNode& node);
0415 
0416 /**
0417  * Convert KoXmlNode classes to the corresponding QDom classes, which has
0418  * @p ownerDoc as the owner document (QDomDocument instance).
0419  * The converted @p element (and its children) is added to ownerDoc.
0420  * 
0421  * NOTE: If ownerDoc is not empty, this may fail, @see QDomDocument
0422  *
0423  */
0424 KOSTORE_EXPORT void asQDomElement(QDomDocument& ownerDoc, const KoXmlElement& element);
0425 
0426 /**
0427  * Converts the whole @p document into a QDomDocument
0428  * If KOXML_USE_QDOM is defined, just returns @p document
0429  */
0430 KOSTORE_EXPORT QDomDocument asQDomDocument(const KoXmlDocument& document);
0431 
0432 /*
0433  * Load an XML document from specified device to a document. You can of
0434  * course use it with QFile (which inherits QIODevice).
0435  * This is much more memory efficient than standard QDomDocument::setContent
0436  * because the data from the device is buffered, unlike
0437  * QDomDocument::setContent which just loads everything in memory.
0438  *
0439  * Note: it is assumed that the XML uses UTF-8 encoding.
0440  */
0441 KOSTORE_EXPORT bool setDocument(KoXmlDocument& doc, QIODevice* device,
0442                                 bool namespaceProcessing, QString* errorMsg = 0,
0443                                 int* errorLine = 0, int* errorColumn = 0);
0444 }
0445 
0446 /**
0447  * \def forEachElement( elem, parent )
0448  * \brief Loop through all child elements of \p parent.
0449  * This convenience macro is used to implement the forEachElement loop.
0450  * The \p elem parameter is a name of a QDomElement variable and the \p parent
0451  * is the name of the parent element. For example:
0452  *
0453  * \code
0454  * QDomElement e;
0455  * forEachElement( e, parent )
0456  * {
0457  *     kDebug() << e.localName() << " element found.";
0458  *     ...
0459  * }
0460  * \endcode
0461  */
0462 #define forEachElement( elem, parent ) \
0463     for ( KoXmlNode _node = parent.firstChild(); !_node.isNull(); _node = _node.nextSibling() ) \
0464         if ( ( elem = _node.toElement() ).isNull() ) {} else
0465 
0466 
0467 #endif // KO_XMLREADER_H