/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** As a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PatternistSDK_XMLWriter_H #define PatternistSDK_XMLWriter_H #include "Global.h" #include #include QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QIODevice; namespace QPatternistSDK { /** * @short Serializes a stream of SAX events into XML, sent to a QIODevice. * * XMLWriter is a fast and simple XML serializer which takes care of * all the low level details of well-formedness and character escaping, allowing * the user to focus on higher level issues and increasing the chances of producing * valid, interoperable XML. * * The content XMLWriter produces is sent to a QIODevice, which is either * specified in XMLWriter's constructor or via setDevice(). If writing to * the device fails, the content functions such as startElement() returns @c false. * * XMLWriter sub-classes QXmlContentHandler meaning it can serialize content * from any code that produces SAX events. The class can also be used manually, * by calling startElement(), endCDATA(), and so forth. * * XMLWriter cannot be used to serialize multiple documents. One instance per * document must be used. * * XMLWriter takes care of escaping content into character references as necessary. Thus, * it should not be done manually. In fact, it would most likely * result in invalid XML or an unintended result. XMLWriter always serializes into UTF-8. * * When compiled in debug mode, XMLWriter contains several tests that helps * ensuring that XMLWriter produces valid XML. Some of these tests ensures that: * * - The @c xmlns and @c xml prefixes are used properly * - Content of comments and processing instructions is valid * - Element, attribute and DOCTYPE names are sensible * - Elements are properly nested and balanced * - To some extent that things occur in the proper order. For example, that * the document type definition isn't added inside an element * - That namespaces prefixes are declared * * Not triggering XMLWriter's tests does not guarantee valid XML is produced, * but they do help catching common mistakes and some of the corner cases in the * specifications. When XMLWriter is compiled in release mode, these tests are not enabled * and the error handling in effect is concerning writing to the QIODevice. * * Often it is of interest to add a note at the beginning of the file communicating * it is auto-generated. setMessage() and setAddMessage() provides * a convenient way of doing that. * * Namespace declarations are added with startPrefixMapping(), not by sending attributes * with name xmlns:* to startElement(). * * @see HOWTO Avoid Being * Called a Bozo When Producing XML * @see Extensible Markup * Language (XML) 1.0 (Third Edition) * @see Namespaces in XML * @todo Replace this class with QXmlStreamWriter * @author Frans Englich * @ingroup PatternistSDK */ class Q_PATTERNISTSDK_EXPORT XMLWriter : public QXmlContentHandler , public QXmlLexicalHandler { public: /** * Creates a XMLWriter which serializes its received events * to @p outStream. * * @note XMLWriter does not claim ownership of @p outStream. Thus, * @p outStream may not be destroyed as long as * this XMLWriter instance uses it. */ XMLWriter(QIODevice *outStream = 0); virtual ~XMLWriter(); /** * @returns @c true if opening the output device succeeds, otherwise @c false */ virtual bool startDocument(); /** * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool characters(const QString &ch); /** * Starts an element with name @p qName and attributes @p atts. The prefix * in @p qName must first be declared with startPrefixMapping(), if it has one. * * A call to startElement() must always at some point be balanced with a call * to endElement(). * * To declare namespaces, don't put attributes with name xmlns:* in @p atts, * but use startPrefixMapping(). */ virtual bool startElement(const QString &qName, const QXmlAttributes &atts = QXmlAttributes()); /** * * Behaves essentially as startElement(const QString &qName, const QXmlAttributes &atts). This * function is used in conjunction with other SAX classes. * * The call: * * @code * startElement(QString(), QString(), qName, atts); * @endcode * * is equivalent to: * * @code * startElement(qName, atts); * @endcode * * @p namespaceURI and @p localName are not used. This function is * used in conjunction with other SAX classes. * * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts); /** * Signals the end of an element with name @p qName. @p qName must * be supplied. * * Calls to startElement() and endElement() must always be balanced. * * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool endElement(const QString &qName); /** * Behaves essentially as endElement(const QString &qName). This function * is used when XMLWriter is used in SAX code. * * @p namespaceURI and @p localName are not used. * * The call: * * @code * endElement(QString(), QString(), qName); * @endcode * * is equivalent to: * * @code * endElement(qName); * @endcode * * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName); /** * A description of an error if it occurred. This is typically * QIODevice::errorString(). If no error has occurred, an empty * string is returned. */ virtual QString errorString() const; /** * Starts a CDATA section. Content sent with characters() will not be escaped * except for ">" if occurring in "]]>". * * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool startCDATA(); /** * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool endCDATA(); /** * Creates a document type definition. * * For example, the code snippet: * * @code * writer.startDTD("html", "-//W3C//DTD XHTML 1.0 Strict//EN", * "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); * writer.endDTD(); * @endcode * * would create: * @verbatim @endverbatim * * @note A system identifier must always be specified, but a public identifier may * be left out. * * A call to startDTD() must be followed by a call to endDTD(). */ virtual bool startDTD(const QString &name, const QString &publicId, const QString &systemId); /** * Apart from closing the DTD, an new line is also added at end. */ virtual bool endDTD(); /** * Creates a processing instruction by name @p target, and content * @p data. * * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool processingInstruction(const QString &target, const QString &data); /** * Declares a namespace which maps @p prefix to @p namespaceURI. For example, the call: * * @code * startPrefixMapping("xhtml", "http://www.w3.org/1999/xhtml"); * @endcode * * would result in: * * @code * xmlns="http://www.w3.org/1999/xhtml" * @endcode */ virtual bool startPrefixMapping(const QString &prefix, const QString &namespaceURI); /** * Creates a comment with content @p ch. @p ch is escaped, there's * no need to do it manually. For example, calling comment() with @p ch * set to "my comment", results in "" in the output. * * @note if @p ch contains double hyphen("--"), the produced XML will * not be well formed. * * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool comment(const QString &ch); virtual bool startEntity(const QString &name); virtual bool endEntity(const QString &name); /** * Sets the message which is added as a comment if addModificationMessage() * is set to @c true. If no message is specified and addModificationMessage() * is set to @c true, a default message is used. * * @see modificationMessage(), setAddMessage() */ virtual void setMessage(const QString &msg); /** * The message that is added at the beginning of the XML events * in a comment node. If no modificationMessage is set via modificationMessage(), * and addModificationMessage is set to @c true, this message will be used: * "NOTE: This file was automatically generated by [the application name] at * [the current date time]. All changes to this file will be lost." * * @see setMessage() */ virtual QString modificationMessage() const; /** * Closes the QIODevice XMLWriter writes to. */ virtual bool endDocument(); /** * Serializes @p ch as if it was sent to characters(). * * @returns @c false if failure occurs in writing to the QIODevice, otherwise * @c true */ virtual bool ignorableWhitespace(const QString &ch); /** * This function is not used by XMLWriter, but is implemented * in order to satisfy QXmlContentHandler's interface. */ virtual bool endPrefixMapping(const QString &prefix); /** * This function is not used by XMLWriter, but is implemented * in order to satisfy QXmlContentHandler's interface. */ virtual bool skippedEntity(const QString &name); /** * This function is not used by XMLWriter, but is implemented * in order to satisfy QXmlContentHandler's interface. */ virtual void setDocumentLocator(QXmlLocator *); /** * @returns the device XMLWriter writes its output to. * XMLWriter does not own the device. */ virtual QIODevice *device() const; /** * Sets the QIODevice XMLWriter writes to, to @p device. A device must be specified * either via this function or in the constructor before XMLWriter is used. * * XMLWriter does not claim ownership of @p device. */ virtual void setDevice(QIODevice *device); /** * Determines whether the modification message should be inserted as a comment * before the document element. The message returned by modificationMessage() is used. * * If @p toggle is @c true, the message will be added, otherwise not. */ virtual void setAddMessage(const bool toggle); /** * Tells whether a modification message will be added. * * @see setAddMessage(), modificationMessage() */ virtual bool addModificationMessage() const; private: Q_DISABLE_COPY(XMLWriter) class Private; Private *d; }; } QT_END_NAMESPACE QT_END_HEADER #endif // vim: et:ts=4:sw=4:sts=4