util/src/xml/dom/qdom.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtXml module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <qplatformdefs.h>
       
    43 #include <qdom.h>
       
    44 #include "private/qxmlutils_p.h"
       
    45 
       
    46 #ifndef QT_NO_DOM
       
    47 
       
    48 #include <qatomic.h>
       
    49 #include <qbuffer.h>
       
    50 #include <qhash.h>
       
    51 #include <qiodevice.h>
       
    52 #include <qlist.h>
       
    53 #include <qregexp.h>
       
    54 #include <qtextcodec.h>
       
    55 #include <qtextstream.h>
       
    56 #include <qxml.h>
       
    57 #include <qvariant.h>
       
    58 #include <qmap.h>
       
    59 #include <qshareddata.h>
       
    60 #include <qdebug.h>
       
    61 #include <stdio.h>
       
    62 
       
    63 QT_BEGIN_NAMESPACE
       
    64 
       
    65 /*
       
    66   ### old todo comments -- I don't know if they still apply...
       
    67 
       
    68   If the document dies, remove all pointers to it from children
       
    69   which can not be deleted at this time.
       
    70 
       
    71   If a node dies and has direct children which can not be deleted,
       
    72   then remove the pointer to the parent.
       
    73 
       
    74   createElement and friends create double reference counts.
       
    75 */
       
    76 
       
    77 /* ##### new TODOs:
       
    78 
       
    79   Remove emtpy emthods in the *Private classes
       
    80 
       
    81   Make a lot of the (mostly empty) methods in the public classes inline.
       
    82   Specially constructors assignment operators and comparison operators are candidates.
       
    83 
       
    84   The virtual isXxx functions in *Private can probably be replaced by inline methods checking the nodeType().
       
    85 */
       
    86 
       
    87 /*
       
    88   Reference counting:
       
    89 
       
    90   Some simple rules:
       
    91   1) If an intern object returns a pointer to another intern object
       
    92      then the reference count of the returned object is not increased.
       
    93   2) If an extern object is created and gets a pointer to some intern
       
    94      object, then the extern object increases the intern objects reference count.
       
    95   3) If an extern object is deleted, then it decreases the reference count
       
    96      on its associated intern object and deletes it if nobody else hold references
       
    97      on the intern object.
       
    98 */
       
    99 
       
   100 
       
   101 /*
       
   102   Helper to split a qualified name in the prefix and local name.
       
   103 */
       
   104 static void qt_split_namespace(QString& prefix, QString& name, const QString& qName, bool hasURI)
       
   105 {
       
   106     int i = qName.indexOf(QLatin1Char(':'));
       
   107     if (i == -1) {
       
   108         if (hasURI)
       
   109             prefix = QLatin1String("");
       
   110         else
       
   111             prefix.clear();
       
   112         name = qName;
       
   113     } else {
       
   114         prefix = qName.left(i);
       
   115         name = qName.mid(i + 1);
       
   116     }
       
   117 }
       
   118 
       
   119 /**************************************************************
       
   120  *
       
   121  * Private class declerations
       
   122  *
       
   123  **************************************************************/
       
   124 
       
   125 class QDomImplementationPrivate
       
   126 {
       
   127 public:
       
   128     inline QDomImplementationPrivate() {}
       
   129 
       
   130     QDomImplementationPrivate* clone();
       
   131     QAtomicInt ref;
       
   132     static QDomImplementation::InvalidDataPolicy invalidDataPolicy;
       
   133 };
       
   134 
       
   135 class QDomNodePrivate
       
   136 {
       
   137 public:
       
   138     QDomNodePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = 0);
       
   139     QDomNodePrivate(QDomNodePrivate* n, bool deep);
       
   140     virtual ~QDomNodePrivate();
       
   141 
       
   142     QString nodeName() const { return name; }
       
   143     QString nodeValue() const { return value; }
       
   144     virtual void setNodeValue(const QString& v) { value = v; }
       
   145 
       
   146     QDomDocumentPrivate* ownerDocument();
       
   147     void setOwnerDocument(QDomDocumentPrivate* doc);
       
   148 
       
   149     virtual QDomNodePrivate* insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild);
       
   150     virtual QDomNodePrivate* insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild);
       
   151     virtual QDomNodePrivate* replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild);
       
   152     virtual QDomNodePrivate* removeChild(QDomNodePrivate* oldChild);
       
   153     virtual QDomNodePrivate* appendChild(QDomNodePrivate* newChild);
       
   154 
       
   155     QDomNodePrivate* namedItem(const QString& name);
       
   156 
       
   157     virtual QDomNodePrivate* cloneNode(bool deep = true);
       
   158     virtual void normalize();
       
   159     virtual void clear();
       
   160 
       
   161     inline QDomNodePrivate* parent() const { return hasParent ? ownerNode : 0; }
       
   162     inline void setParent(QDomNodePrivate *p) { ownerNode = p; hasParent = true; }
       
   163 
       
   164     void setNoParent() {
       
   165         ownerNode = hasParent ? (QDomNodePrivate*)ownerDocument() : 0;
       
   166         hasParent = false;
       
   167     }
       
   168 
       
   169     // Dynamic cast
       
   170     virtual bool isAttr() const                     { return false; }
       
   171     virtual bool isCDATASection() const             { return false; }
       
   172     virtual bool isDocumentFragment() const         { return false; }
       
   173     virtual bool isDocument() const                 { return false; }
       
   174     virtual bool isDocumentType() const             { return false; }
       
   175     virtual bool isElement() const                  { return false; }
       
   176     virtual bool isEntityReference() const          { return false; }
       
   177     virtual bool isText() const                     { return false; }
       
   178     virtual bool isEntity() const                   { return false; }
       
   179     virtual bool isNotation() const                 { return false; }
       
   180     virtual bool isProcessingInstruction() const    { return false; }
       
   181     virtual bool isCharacterData() const            { return false; }
       
   182     virtual bool isComment() const                  { return false; }
       
   183 
       
   184     virtual QDomNode::NodeType nodeType() const { return QDomNode::BaseNode; }
       
   185 
       
   186     virtual void save(QTextStream&, int, int) const;
       
   187 
       
   188     void setLocation(int lineNumber, int columnNumber);
       
   189 
       
   190     // Variables
       
   191     QAtomicInt ref;
       
   192     QDomNodePrivate* prev;
       
   193     QDomNodePrivate* next;
       
   194     QDomNodePrivate* ownerNode; // either the node's parent or the node's owner document
       
   195     QDomNodePrivate* first;
       
   196     QDomNodePrivate* last;
       
   197 
       
   198     QString name; // this is the local name if prefix != null
       
   199     QString value;
       
   200     QString prefix; // set this only for ElementNode and AttributeNode
       
   201     QString namespaceURI; // set this only for ElementNode and AttributeNode
       
   202     bool createdWithDom1Interface : 1;
       
   203     bool hasParent                : 1;
       
   204 
       
   205     int lineNumber;
       
   206     int columnNumber;
       
   207 };
       
   208 
       
   209 class QDomNodeListPrivate
       
   210 {
       
   211 public:
       
   212     QDomNodeListPrivate(QDomNodePrivate*);
       
   213     QDomNodeListPrivate(QDomNodePrivate*, const QString& );
       
   214     QDomNodeListPrivate(QDomNodePrivate*, const QString&, const QString& );
       
   215     ~QDomNodeListPrivate();
       
   216 
       
   217     bool operator== (const QDomNodeListPrivate&) const;
       
   218     bool operator!= (const QDomNodeListPrivate&) const;
       
   219 
       
   220     void createList();
       
   221     QDomNodePrivate* item(int index);
       
   222     uint length() const;
       
   223 
       
   224     QAtomicInt ref;
       
   225     /*
       
   226       This list contains the children of this node.
       
   227      */
       
   228     QDomNodePrivate* node_impl;
       
   229     QString tagname;
       
   230     QString nsURI;
       
   231     QList<QDomNodePrivate*> list;
       
   232     long timestamp;
       
   233 };
       
   234 
       
   235 class QDomNamedNodeMapPrivate
       
   236 {
       
   237 public:
       
   238     QDomNamedNodeMapPrivate(QDomNodePrivate*);
       
   239     ~QDomNamedNodeMapPrivate();
       
   240 
       
   241     QDomNodePrivate* namedItem(const QString& name) const;
       
   242     QDomNodePrivate* namedItemNS(const QString& nsURI, const QString& localName) const;
       
   243     QDomNodePrivate* setNamedItem(QDomNodePrivate* arg);
       
   244     QDomNodePrivate* setNamedItemNS(QDomNodePrivate* arg);
       
   245     QDomNodePrivate* removeNamedItem(const QString& name);
       
   246     QDomNodePrivate* item(int index) const;
       
   247     uint length() const;
       
   248     bool contains(const QString& name) const;
       
   249     bool containsNS(const QString& nsURI, const QString & localName) const;
       
   250 
       
   251     /**
       
   252      * Remove all children from the map.
       
   253      */
       
   254     void clearMap();
       
   255     bool isReadOnly() { return readonly; }
       
   256     void setReadOnly(bool r) { readonly = r; }
       
   257     bool isAppendToParent() { return appendToParent; }
       
   258     /**
       
   259      * If true, then the node will redirect insert/remove calls
       
   260      * to its parent by calling QDomNodePrivate::appendChild or removeChild.
       
   261      * In addition the map wont increase or decrease the reference count
       
   262      * of the nodes it contains.
       
   263      *
       
   264      * By default this value is false and the map will handle reference counting
       
   265      * by itself.
       
   266      */
       
   267     void setAppendToParent(bool b) { appendToParent = b; }
       
   268 
       
   269     /**
       
   270      * Creates a copy of the map. It is a deep copy
       
   271      * that means that all children are cloned.
       
   272      */
       
   273     QDomNamedNodeMapPrivate* clone(QDomNodePrivate* parent);
       
   274 
       
   275     // Variables
       
   276     QAtomicInt ref;
       
   277     QHash<QString, QDomNodePrivate *> map;
       
   278     QDomNodePrivate* parent;
       
   279     bool readonly;
       
   280     bool appendToParent;
       
   281 };
       
   282 
       
   283 class QDomDocumentTypePrivate : public QDomNodePrivate
       
   284 {
       
   285 public:
       
   286     QDomDocumentTypePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = 0);
       
   287     QDomDocumentTypePrivate(QDomDocumentTypePrivate* n, bool deep);
       
   288     ~QDomDocumentTypePrivate();
       
   289     void init();
       
   290 
       
   291     // Reimplemented from QDomNodePrivate
       
   292     QDomNodePrivate* cloneNode(bool deep = true);
       
   293     QDomNodePrivate* insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild);
       
   294     QDomNodePrivate* insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild);
       
   295     QDomNodePrivate* replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild);
       
   296     QDomNodePrivate* removeChild(QDomNodePrivate* oldChild);
       
   297     QDomNodePrivate* appendChild(QDomNodePrivate* newChild);
       
   298 
       
   299     virtual bool isDocumentType() const { return true; }
       
   300     QDomNode::NodeType nodeType() const { return QDomNode::DocumentTypeNode; }
       
   301 
       
   302     void save(QTextStream& s, int, int) const;
       
   303 
       
   304     // Variables
       
   305     QDomNamedNodeMapPrivate* entities;
       
   306     QDomNamedNodeMapPrivate* notations;
       
   307     QString publicId;
       
   308     QString systemId;
       
   309     QString internalSubset;
       
   310 };
       
   311 
       
   312 class QDomDocumentFragmentPrivate : public QDomNodePrivate
       
   313 {
       
   314 public:
       
   315     QDomDocumentFragmentPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = 0);
       
   316     QDomDocumentFragmentPrivate(QDomNodePrivate* n, bool deep);
       
   317 
       
   318     // Reimplemented from QDomNodePrivate
       
   319     virtual QDomNodePrivate* cloneNode(bool deep = true);
       
   320     virtual bool isDocumentFragment() const { return true; }
       
   321     QDomNode::NodeType nodeType() const { return QDomNode::DocumentFragmentNode; }
       
   322 };
       
   323 
       
   324 class QDomCharacterDataPrivate : public QDomNodePrivate
       
   325 {
       
   326 public:
       
   327     QDomCharacterDataPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& data);
       
   328     QDomCharacterDataPrivate(QDomCharacterDataPrivate* n, bool deep);
       
   329 
       
   330     uint dataLength() const;
       
   331     QString substringData(unsigned long offset, unsigned long count) const;
       
   332     void appendData(const QString& arg);
       
   333     void insertData(unsigned long offset, const QString& arg);
       
   334     void deleteData(unsigned long offset, unsigned long count);
       
   335     void replaceData(unsigned long offset, unsigned long count, const QString& arg);
       
   336 
       
   337     // Reimplemented from QDomNodePrivate
       
   338     virtual bool isCharacterData() const { return true; }
       
   339     QDomNode::NodeType nodeType() const { return QDomNode::CharacterDataNode; }
       
   340     QDomNodePrivate* cloneNode(bool deep = true);
       
   341 };
       
   342 
       
   343 class QDomTextPrivate : public QDomCharacterDataPrivate
       
   344 {
       
   345 public:
       
   346     QDomTextPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val);
       
   347     QDomTextPrivate(QDomTextPrivate* n, bool deep);
       
   348 
       
   349     QDomTextPrivate* splitText(int offset);
       
   350 
       
   351     // Reimplemented from QDomNodePrivate
       
   352     QDomNodePrivate* cloneNode(bool deep = true);
       
   353     virtual bool isText() const { return true; }
       
   354     QDomNode::NodeType nodeType() const { return QDomNode::TextNode; }
       
   355     virtual void save(QTextStream& s, int, int) const;
       
   356 };
       
   357 
       
   358 class QDomAttrPrivate : public QDomNodePrivate
       
   359 {
       
   360 public:
       
   361     QDomAttrPrivate(QDomDocumentPrivate*, QDomNodePrivate*, const QString& name);
       
   362     QDomAttrPrivate(QDomDocumentPrivate*, QDomNodePrivate*, const QString& nsURI, const QString& qName);
       
   363     QDomAttrPrivate(QDomAttrPrivate* n, bool deep);
       
   364 
       
   365     bool specified() const;
       
   366 
       
   367     // Reimplemented from QDomNodePrivate
       
   368     void setNodeValue(const QString& v);
       
   369     QDomNodePrivate* cloneNode(bool deep = true);
       
   370     virtual bool isAttr() const { return true; }
       
   371     QDomNode::NodeType nodeType() const { return QDomNode::AttributeNode; }
       
   372     virtual void save(QTextStream& s, int, int) const;
       
   373 
       
   374     // Variables
       
   375     bool m_specified;
       
   376 };
       
   377 
       
   378 class QDomElementPrivate : public QDomNodePrivate
       
   379 {
       
   380 public:
       
   381     QDomElementPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name);
       
   382     QDomElementPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& nsURI, const QString& qName);
       
   383     QDomElementPrivate(QDomElementPrivate* n, bool deep);
       
   384     ~QDomElementPrivate();
       
   385 
       
   386     QString attribute(const QString& name, const QString& defValue) const;
       
   387     QString attributeNS(const QString& nsURI, const QString& localName, const QString& defValue) const;
       
   388     void setAttribute(const QString& name, const QString& value);
       
   389     void setAttributeNS(const QString& nsURI, const QString& qName, const QString& newValue);
       
   390     void removeAttribute(const QString& name);
       
   391     QDomAttrPrivate* attributeNode(const QString& name);
       
   392     QDomAttrPrivate* attributeNodeNS(const QString& nsURI, const QString& localName);
       
   393     QDomAttrPrivate* setAttributeNode(QDomAttrPrivate* newAttr);
       
   394     QDomAttrPrivate* setAttributeNodeNS(QDomAttrPrivate* newAttr);
       
   395     QDomAttrPrivate* removeAttributeNode(QDomAttrPrivate* oldAttr);
       
   396     bool hasAttribute(const QString& name);
       
   397     bool hasAttributeNS(const QString& nsURI, const QString& localName);
       
   398 
       
   399     QString text();
       
   400 
       
   401     // Reimplemented from QDomNodePrivate
       
   402     QDomNamedNodeMapPrivate* attributes() { return m_attr; }
       
   403     bool hasAttributes() { return (m_attr->length() > 0); }
       
   404     virtual bool isElement() const { return true; }
       
   405     QDomNode::NodeType nodeType() const { return QDomNode::ElementNode; }
       
   406     QDomNodePrivate* cloneNode(bool deep = true);
       
   407     virtual void save(QTextStream& s, int, int) const;
       
   408 
       
   409     // Variables
       
   410     QDomNamedNodeMapPrivate* m_attr;
       
   411 };
       
   412 
       
   413 
       
   414 class QDomCommentPrivate : public QDomCharacterDataPrivate
       
   415 {
       
   416 public:
       
   417     QDomCommentPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val);
       
   418     QDomCommentPrivate(QDomCommentPrivate* n, bool deep);
       
   419 
       
   420     // Reimplemented from QDomNodePrivate
       
   421     QDomNodePrivate* cloneNode(bool deep = true);
       
   422     virtual bool isComment() const { return true; }
       
   423     QDomNode::NodeType nodeType() const { return QDomNode::CommentNode; }
       
   424     virtual void save(QTextStream& s, int, int) const;
       
   425 };
       
   426 
       
   427 class QDomCDATASectionPrivate : public QDomTextPrivate
       
   428 {
       
   429 public:
       
   430     QDomCDATASectionPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val);
       
   431     QDomCDATASectionPrivate(QDomCDATASectionPrivate* n, bool deep);
       
   432 
       
   433     // Reimplemented from QDomNodePrivate
       
   434     QDomNodePrivate* cloneNode(bool deep = true);
       
   435     virtual bool isCDATASection() const { return true; }
       
   436     QDomNode::NodeType nodeType() const { return QDomNode::CDATASectionNode; }
       
   437     virtual void save(QTextStream& s, int, int) const;
       
   438 };
       
   439 
       
   440 class QDomNotationPrivate : public QDomNodePrivate
       
   441 {
       
   442 public:
       
   443     QDomNotationPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name,
       
   444                           const QString& pub, const QString& sys);
       
   445     QDomNotationPrivate(QDomNotationPrivate* n, bool deep);
       
   446 
       
   447     // Reimplemented from QDomNodePrivate
       
   448     QDomNodePrivate* cloneNode(bool deep = true);
       
   449     virtual bool isNotation() const { return true; }
       
   450     QDomNode::NodeType nodeType() const { return QDomNode::NotationNode; }
       
   451     virtual void save(QTextStream& s, int, int) const;
       
   452 
       
   453     // Variables
       
   454     QString m_sys;
       
   455     QString m_pub;
       
   456 };
       
   457 
       
   458 class QDomEntityPrivate : public QDomNodePrivate
       
   459 {
       
   460 public:
       
   461     QDomEntityPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name,
       
   462                         const QString& pub, const QString& sys, const QString& notation);
       
   463     QDomEntityPrivate(QDomEntityPrivate* n, bool deep);
       
   464 
       
   465     // Reimplemented from QDomNodePrivate
       
   466     QDomNodePrivate* cloneNode(bool deep = true);
       
   467     virtual bool isEntity() const { return true; }
       
   468     QDomNode::NodeType nodeType() const { return QDomNode::EntityNode; }
       
   469     virtual void save(QTextStream& s, int, int) const;
       
   470 
       
   471     // Variables
       
   472     QString m_sys;
       
   473     QString m_pub;
       
   474     QString m_notationName;
       
   475 };
       
   476 
       
   477 class QDomEntityReferencePrivate : public QDomNodePrivate
       
   478 {
       
   479 public:
       
   480     QDomEntityReferencePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name);
       
   481     QDomEntityReferencePrivate(QDomNodePrivate* n, bool deep);
       
   482 
       
   483     // Reimplemented from QDomNodePrivate
       
   484     QDomNodePrivate* cloneNode(bool deep = true);
       
   485     bool isEntityReference() const { return true; }
       
   486     QDomNode::NodeType nodeType() const { return QDomNode::EntityReferenceNode; }
       
   487     virtual void save(QTextStream& s, int, int) const;
       
   488 };
       
   489 
       
   490 class QDomProcessingInstructionPrivate : public QDomNodePrivate
       
   491 {
       
   492 public:
       
   493     QDomProcessingInstructionPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& target,
       
   494                                        const QString& data);
       
   495     QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate* n, bool deep);
       
   496 
       
   497     // Reimplemented from QDomNodePrivate
       
   498     QDomNodePrivate* cloneNode(bool deep = true);
       
   499     virtual bool isProcessingInstruction() const { return true; }
       
   500     QDomNode::NodeType nodeType() const { return QDomNode::ProcessingInstructionNode; }
       
   501     virtual void save(QTextStream& s, int, int) const;
       
   502 };
       
   503 
       
   504 class QDomDocumentPrivate : public QDomNodePrivate
       
   505 {
       
   506 public:
       
   507     QDomDocumentPrivate();
       
   508     QDomDocumentPrivate(const QString& name);
       
   509     QDomDocumentPrivate(QDomDocumentTypePrivate* dt);
       
   510     QDomDocumentPrivate(QDomDocumentPrivate* n, bool deep);
       
   511     ~QDomDocumentPrivate();
       
   512 
       
   513     bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn);
       
   514     bool setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn);
       
   515 
       
   516     // Attributes
       
   517     QDomDocumentTypePrivate* doctype() { return type.data(); }
       
   518     QDomImplementationPrivate* implementation() { return impl.data(); }
       
   519     QDomElementPrivate* documentElement();
       
   520 
       
   521     // Factories
       
   522     QDomElementPrivate* createElement(const QString& tagName);
       
   523     QDomElementPrivate*        createElementNS(const QString& nsURI, const QString& qName);
       
   524     QDomDocumentFragmentPrivate* createDocumentFragment();
       
   525     QDomTextPrivate* createTextNode(const QString& data);
       
   526     QDomCommentPrivate* createComment(const QString& data);
       
   527     QDomCDATASectionPrivate* createCDATASection(const QString& data);
       
   528     QDomProcessingInstructionPrivate* createProcessingInstruction(const QString& target, const QString& data);
       
   529     QDomAttrPrivate* createAttribute(const QString& name);
       
   530     QDomAttrPrivate* createAttributeNS(const QString& nsURI, const QString& qName);
       
   531     QDomEntityReferencePrivate* createEntityReference(const QString& name);
       
   532 
       
   533     QDomNodePrivate* importNode(const QDomNodePrivate* importedNode, bool deep);
       
   534 
       
   535     // Reimplemented from QDomNodePrivate
       
   536     QDomNodePrivate* cloneNode(bool deep = true);
       
   537     bool isDocument() const { return true; }
       
   538     QDomNode::NodeType nodeType() const { return QDomNode::DocumentNode; }
       
   539     void clear();
       
   540 
       
   541     // Variables
       
   542     QExplicitlySharedDataPointer<QDomImplementationPrivate> impl;
       
   543     QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type;
       
   544 
       
   545     void saveDocument(QTextStream& stream, const int indent, QDomNode::EncodingPolicy encUsed) const;
       
   546 
       
   547     /* \internal
       
   548        Counter for the QDomNodeListPrivate timestamps.
       
   549 
       
   550        This is a cache optimization, that might in some cases be effective. The
       
   551        dilemma is that QDomNode::childNodes() returns a list, but the
       
   552        implementation stores the children in a linked list. Hence, in order to
       
   553        get the children out through childNodes(), a list must be populated each
       
   554        time, which is O(N).
       
   555 
       
   556        DOM has the requirement of node references being live, see DOM Core
       
   557        Level 3, 1.1.1 The DOM Structure Model, which means that changes to the
       
   558        underlying documents must be reflected in node lists.
       
   559 
       
   560        This mechanism, nodeListTime, is a caching optimization that reduces the
       
   561        amount of times the node list is rebuilt, by only doing so when the
       
   562        document actually changes. However, a change to anywhere in any document
       
   563        invalidate all lists, since no dependency tracking is done.
       
   564 
       
   565        It functions by that all modifying functions(insertBefore() and so on)
       
   566        increment the count; each QDomNodeListPrivate copies nodeListTime on
       
   567        construction, and compares its own value to nodeListTime in order to
       
   568        determine whether it needs to rebuild.
       
   569 
       
   570        This is reentrant. The nodeListTime may overflow, but that's ok since we
       
   571        check for equalness, not whether nodeListTime is smaller than the list's
       
   572        stored timestamp.
       
   573     */
       
   574     long nodeListTime;
       
   575 };
       
   576 
       
   577 /**************************************************************
       
   578  *
       
   579  * QDomHandler
       
   580  *
       
   581  **************************************************************/
       
   582 
       
   583 class QDomHandler : public QXmlDefaultHandler
       
   584 {
       
   585 public:
       
   586     QDomHandler(QDomDocumentPrivate* d, bool namespaceProcessing);
       
   587     ~QDomHandler();
       
   588 
       
   589     // content handler
       
   590     bool endDocument();
       
   591     bool startElement(const QString& nsURI, const QString& localName, const QString& qName, const QXmlAttributes& atts);
       
   592     bool endElement(const QString& nsURI, const QString& localName, const QString& qName);
       
   593     bool characters(const QString& ch);
       
   594     bool processingInstruction(const QString& target, const QString& data);
       
   595     bool skippedEntity(const QString& name);
       
   596 
       
   597     // error handler
       
   598     bool fatalError(const QXmlParseException& exception);
       
   599 
       
   600     // lexical handler
       
   601     bool startCDATA();
       
   602     bool endCDATA();
       
   603     bool startEntity(const QString &);
       
   604     bool endEntity(const QString &);
       
   605     bool startDTD(const QString& name, const QString& publicId, const QString& systemId);
       
   606     bool comment(const QString& ch);
       
   607 
       
   608     // decl handler
       
   609     bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId) ;
       
   610 
       
   611     // DTD handler
       
   612     bool notationDecl(const QString & name, const QString & publicId, const QString & systemId);
       
   613     bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName) ;
       
   614 
       
   615     void setDocumentLocator(QXmlLocator *locator);
       
   616 
       
   617     QString errorMsg;
       
   618     int errorLine;
       
   619     int errorColumn;
       
   620 
       
   621 private:
       
   622     QDomDocumentPrivate *doc;
       
   623     QDomNodePrivate *node;
       
   624     QString entityName;
       
   625     bool cdata;
       
   626     bool nsProcessing;
       
   627     QXmlLocator *locator;
       
   628 };
       
   629 
       
   630 /**************************************************************
       
   631  *
       
   632  * Functions for verifying legal data
       
   633  *
       
   634  **************************************************************/
       
   635 QDomImplementation::InvalidDataPolicy QDomImplementationPrivate::invalidDataPolicy
       
   636     = QDomImplementation::AcceptInvalidChars;
       
   637 
       
   638 // [5] Name ::= (Letter | '_' | ':') (NameChar)*
       
   639 
       
   640 static QString fixedXmlName(const QString &_name, bool *ok, bool namespaces = false)
       
   641 {
       
   642     QString name, prefix;
       
   643     if (namespaces)
       
   644         qt_split_namespace(prefix, name, _name, true);
       
   645     else
       
   646         name = _name;
       
   647 
       
   648     if (name.isEmpty()) {
       
   649         *ok = false;
       
   650         return QString();
       
   651     }
       
   652 
       
   653     if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::AcceptInvalidChars) {
       
   654         *ok = true;
       
   655         return _name;
       
   656     }
       
   657 
       
   658     QString result;
       
   659     bool firstChar = true;
       
   660     for (int i = 0; i < name.size(); ++i) {
       
   661         QChar c = name.at(i);
       
   662         if (firstChar) {
       
   663             if (QXmlUtils::isLetter(c) || c.unicode() == '_' || c.unicode() == ':') {
       
   664                 result.append(c);
       
   665                 firstChar = false;
       
   666             } else if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   667                 *ok = false;
       
   668                 return QString();
       
   669             }
       
   670         } else {
       
   671             if (QXmlUtils::isNameChar(c))
       
   672                 result.append(c);
       
   673             else if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   674                 *ok = false;
       
   675                 return QString();
       
   676             }
       
   677         }
       
   678     }
       
   679 
       
   680     if (result.isEmpty()) {
       
   681         *ok = false;
       
   682         return QString();
       
   683     }
       
   684 
       
   685     *ok = true;
       
   686     if (namespaces && !prefix.isEmpty())
       
   687         return prefix + QLatin1Char(':') + result;
       
   688     return result;
       
   689 }
       
   690 
       
   691 // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
       
   692 // '<', '&' and "]]>" will be escaped when writing
       
   693 
       
   694 static QString fixedCharData(const QString &data, bool *ok)
       
   695 {
       
   696     if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::AcceptInvalidChars) {
       
   697         *ok = true;
       
   698         return data;
       
   699     }
       
   700 
       
   701     QString result;
       
   702     for (int i = 0; i < data.size(); ++i) {
       
   703         QChar c = data.at(i);
       
   704         if (QXmlUtils::isChar(c)) {
       
   705             result.append(c);
       
   706         } else if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   707             *ok = false;
       
   708             return QString();
       
   709         }
       
   710     }
       
   711 
       
   712     *ok = true;
       
   713     return result;
       
   714 }
       
   715 
       
   716 // [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
       
   717 // can't escape "--", since entities are not recognised within comments
       
   718 
       
   719 static QString fixedComment(const QString &data, bool *ok)
       
   720 {
       
   721     if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::AcceptInvalidChars) {
       
   722         *ok = true;
       
   723         return data;
       
   724     }
       
   725 
       
   726     QString fixedData = fixedCharData(data, ok);
       
   727     if (!*ok)
       
   728         return QString();
       
   729 
       
   730     for (;;) {
       
   731         int idx = fixedData.indexOf(QLatin1String("--"));
       
   732         if (idx == -1)
       
   733             break;
       
   734         if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   735             *ok = false;
       
   736             return QString();
       
   737         }
       
   738         fixedData.remove(idx, 2);
       
   739     }
       
   740 
       
   741     *ok = true;
       
   742     return fixedData;
       
   743 }
       
   744 
       
   745 // [20] CData ::= (Char* - (Char* ']]>' Char*))
       
   746 // can't escape "]]>", since entities are not recognised within comments
       
   747 
       
   748 static QString fixedCDataSection(const QString &data, bool *ok)
       
   749 {
       
   750     if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::AcceptInvalidChars) {
       
   751         *ok = true;
       
   752         return data;
       
   753     }
       
   754 
       
   755     QString fixedData = fixedCharData(data, ok);
       
   756     if (!*ok)
       
   757         return QString();
       
   758 
       
   759     for (;;) {
       
   760         int idx = fixedData.indexOf(QLatin1String("]]>"));
       
   761         if (idx == -1)
       
   762             break;
       
   763         if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   764             *ok = false;
       
   765             return QString();
       
   766         }
       
   767         fixedData.remove(idx, 3);
       
   768     }
       
   769 
       
   770     *ok = true;
       
   771     return fixedData;
       
   772 }
       
   773 
       
   774 // [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
       
   775 
       
   776 static QString fixedPIData(const QString &data, bool *ok)
       
   777 {
       
   778     if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::AcceptInvalidChars) {
       
   779         *ok = true;
       
   780         return data;
       
   781     }
       
   782 
       
   783     QString fixedData = fixedCharData(data, ok);
       
   784     if (!*ok)
       
   785         return QString();
       
   786 
       
   787     for (;;) {
       
   788         int idx = fixedData.indexOf(QLatin1String("?>"));
       
   789         if (idx == -1)
       
   790             break;
       
   791         if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   792             *ok = false;
       
   793             return QString();
       
   794         }
       
   795         fixedData.remove(idx, 2);
       
   796     }
       
   797 
       
   798     *ok = true;
       
   799     return fixedData;
       
   800 }
       
   801 
       
   802 // [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
       
   803 // The correct quote will be chosen when writing
       
   804 
       
   805 static QString fixedPubidLiteral(const QString &data, bool *ok)
       
   806 {
       
   807     if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::AcceptInvalidChars) {
       
   808         *ok = true;
       
   809         return data;
       
   810     }
       
   811 
       
   812     QString result;
       
   813 
       
   814     if(QXmlUtils::isPublicID(data))
       
   815         result = data;
       
   816     else if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   817         *ok = false;
       
   818         return QString();
       
   819     }
       
   820 
       
   821     if (result.indexOf(QLatin1Char('\'')) != -1
       
   822         && result.indexOf(QLatin1Char('"')) != -1) {
       
   823         if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   824             *ok = false;
       
   825             return QString();
       
   826         } else {
       
   827             result.remove(QLatin1Char('\''));
       
   828         }
       
   829     }
       
   830 
       
   831     *ok = true;
       
   832     return result;
       
   833 }
       
   834 
       
   835 // [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
       
   836 // The correct quote will be chosen when writing
       
   837 
       
   838 static QString fixedSystemLiteral(const QString &data, bool *ok)
       
   839 {
       
   840     if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::AcceptInvalidChars) {
       
   841         *ok = true;
       
   842         return data;
       
   843     }
       
   844 
       
   845     QString result = data;
       
   846 
       
   847     if (result.indexOf(QLatin1Char('\'')) != -1
       
   848         && result.indexOf(QLatin1Char('"')) != -1) {
       
   849         if (QDomImplementationPrivate::invalidDataPolicy == QDomImplementation::ReturnNullNode) {
       
   850             *ok = false;
       
   851             return QString();
       
   852         } else {
       
   853             result.remove(QLatin1Char('\''));
       
   854         }
       
   855     }
       
   856 
       
   857     *ok = true;
       
   858     return result;
       
   859 }
       
   860 
       
   861 /**************************************************************
       
   862  *
       
   863  * QDomImplementationPrivate
       
   864  *
       
   865  **************************************************************/
       
   866 
       
   867 QDomImplementationPrivate* QDomImplementationPrivate::clone()
       
   868 {
       
   869     return new QDomImplementationPrivate;
       
   870 }
       
   871 
       
   872 /**************************************************************
       
   873  *
       
   874  * QDomImplementation
       
   875  *
       
   876  **************************************************************/
       
   877 
       
   878 /*!
       
   879     \class QDomImplementation
       
   880     \reentrant
       
   881     \brief The QDomImplementation class provides information about the
       
   882     features of the DOM implementation.
       
   883 
       
   884     \inmodule QtXml
       
   885     \ingroup xml-tools
       
   886 
       
   887     This class describes the features that are supported by the DOM
       
   888     implementation. Currently the XML subset of DOM Level 1 and DOM
       
   889     Level 2 Core are supported.
       
   890 
       
   891     Normally you will use the function QDomDocument::implementation()
       
   892     to get the implementation object.
       
   893 
       
   894     You can create a new document type with createDocumentType() and a
       
   895     new document with createDocument().
       
   896 
       
   897     For further information about the Document Object Model see
       
   898     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
   899     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}. For a more
       
   900     general introduction of the DOM implementation see the QDomDocument
       
   901     documentation.
       
   902 
       
   903     The QDom classes have a few issues of nonconformance with the XML
       
   904     specifications that cannot be fixed in Qt 4 without breaking backward
       
   905     compatibility. The QtXmlPatterns module and the QXmlStreamReader and
       
   906     QXmlStreamWriter classes have a higher degree of a conformance.
       
   907 
       
   908     \sa hasFeature()
       
   909 */
       
   910 
       
   911 /*!
       
   912     Constructs a QDomImplementation object.
       
   913 */
       
   914 QDomImplementation::QDomImplementation()
       
   915 {
       
   916     impl = 0;
       
   917 }
       
   918 
       
   919 /*!
       
   920     Constructs a copy of \a x.
       
   921 */
       
   922 QDomImplementation::QDomImplementation(const QDomImplementation &x)
       
   923 {
       
   924     impl = x.impl;
       
   925     if (impl)
       
   926         impl->ref.ref();
       
   927 }
       
   928 
       
   929 QDomImplementation::QDomImplementation(QDomImplementationPrivate *p)
       
   930 {
       
   931     // We want to be co-owners, so increase the reference count
       
   932     impl = p;
       
   933     if (impl)
       
   934         impl->ref.ref();
       
   935 }
       
   936 
       
   937 /*!
       
   938     Assigns \a x to this DOM implementation.
       
   939 */
       
   940 QDomImplementation& QDomImplementation::operator=(const QDomImplementation &x)
       
   941 {
       
   942     if (x.impl)
       
   943         x.impl->ref.ref();
       
   944     if (impl && !impl->ref.deref())
       
   945         delete impl;
       
   946     impl = x.impl;
       
   947     return *this;
       
   948 }
       
   949 
       
   950 /*!
       
   951     Returns true if \a x and this DOM implementation object were
       
   952     created from the same QDomDocument; otherwise returns false.
       
   953 */
       
   954 bool QDomImplementation::operator==(const QDomImplementation &x) const
       
   955 {
       
   956     return (impl == x.impl);
       
   957 }
       
   958 
       
   959 /*!
       
   960     Returns true if \a x and this DOM implementation object were
       
   961     created from different QDomDocuments; otherwise returns false.
       
   962 */
       
   963 bool QDomImplementation::operator!=(const QDomImplementation &x) const
       
   964 {
       
   965     return (impl != x.impl);
       
   966 }
       
   967 
       
   968 /*!
       
   969     Destroys the object and frees its resources.
       
   970 */
       
   971 QDomImplementation::~QDomImplementation()
       
   972 {
       
   973     if (impl && !impl->ref.deref())
       
   974         delete impl;
       
   975 }
       
   976 
       
   977 /*!
       
   978     The function returns true if QDom implements the requested \a
       
   979     version of a \a feature; otherwise returns false.
       
   980 
       
   981     The currently supported features and their versions:
       
   982     \table
       
   983     \header \i Feature \i Version
       
   984     \row \i XML \i 1.0
       
   985     \endtable
       
   986 */
       
   987 bool QDomImplementation::hasFeature(const QString& feature, const QString& version) const
       
   988 {
       
   989     if (feature == QLatin1String("XML")) {
       
   990         if (version.isEmpty() || version == QLatin1String("1.0")) {
       
   991             return true;
       
   992         }
       
   993     }
       
   994     // ### add DOM level 2 features
       
   995     return false;
       
   996 }
       
   997 
       
   998 /*!
       
   999     Creates a document type node for the name \a qName.
       
  1000 
       
  1001     \a publicId specifies the public identifier of the external
       
  1002     subset. If you specify an empty string (QString()) as the \a
       
  1003     publicId, this means that the document type has no public
       
  1004     identifier.
       
  1005 
       
  1006     \a systemId specifies the system identifier of the external
       
  1007     subset. If you specify an empty string as the \a systemId, this
       
  1008     means that the document type has no system identifier.
       
  1009 
       
  1010     Since you cannot have a public identifier without a system
       
  1011     identifier, the public identifier is set to an empty string if
       
  1012     there is no system identifier.
       
  1013 
       
  1014     DOM level 2 does not support any other document type declaration
       
  1015     features.
       
  1016 
       
  1017     The only way you can use a document type that was created this
       
  1018     way, is in combination with the createDocument() function to
       
  1019     create a QDomDocument with this document type.
       
  1020 
       
  1021     In the DOM specification, this is the only way to create a non-null
       
  1022     document. For historical reasons, Qt also allows to create the
       
  1023     document using the default empty constructor. The resulting document
       
  1024     is null, but becomes non-null when a factory function, for example
       
  1025     QDomDocument::createElement(), is called. The document also becomes
       
  1026     non-null when setContent() is called.
       
  1027 
       
  1028     \sa createDocument()
       
  1029 */
       
  1030 QDomDocumentType QDomImplementation::createDocumentType(const QString& qName, const QString& publicId, const QString& systemId)
       
  1031 {
       
  1032     bool ok;
       
  1033     QString fixedName = fixedXmlName(qName, &ok, true);
       
  1034     if (!ok)
       
  1035         return QDomDocumentType();
       
  1036 
       
  1037     QString fixedPublicId = fixedPubidLiteral(publicId, &ok);
       
  1038     if (!ok)
       
  1039         return QDomDocumentType();
       
  1040 
       
  1041     QString fixedSystemId = fixedSystemLiteral(systemId, &ok);
       
  1042     if (!ok)
       
  1043         return QDomDocumentType();
       
  1044 
       
  1045     QDomDocumentTypePrivate *dt = new QDomDocumentTypePrivate(0);
       
  1046     dt->name = fixedName;
       
  1047     if (systemId.isNull()) {
       
  1048         dt->publicId.clear();
       
  1049         dt->systemId.clear();
       
  1050     } else {
       
  1051         dt->publicId = fixedPublicId;
       
  1052         dt->systemId = fixedSystemId;
       
  1053     }
       
  1054     dt->ref.deref();
       
  1055     return QDomDocumentType(dt);
       
  1056 }
       
  1057 
       
  1058 /*!
       
  1059     Creates a DOM document with the document type \a doctype. This
       
  1060     function also adds a root element node with the qualified name \a
       
  1061     qName and the namespace URI \a nsURI.
       
  1062 */
       
  1063 QDomDocument QDomImplementation::createDocument(const QString& nsURI, const QString& qName, const QDomDocumentType& doctype)
       
  1064 {
       
  1065     QDomDocument doc(doctype);
       
  1066     QDomElement root = doc.createElementNS(nsURI, qName);
       
  1067     if (root.isNull())
       
  1068         return QDomDocument();
       
  1069     doc.appendChild(root);
       
  1070     return doc;
       
  1071 }
       
  1072 
       
  1073 /*!
       
  1074     Returns false if the object was created by
       
  1075     QDomDocument::implementation(); otherwise returns true.
       
  1076 */
       
  1077 bool QDomImplementation::isNull()
       
  1078 {
       
  1079     return (impl == 0);
       
  1080 }
       
  1081 
       
  1082 /*!
       
  1083     \enum QDomImplementation::InvalidDataPolicy
       
  1084 
       
  1085     This enum specifies what should be done when a factory function
       
  1086     in QDomDocument is called with invalid data.
       
  1087     \value AcceptInvalidChars The data should be stored in the DOM object
       
  1088         anyway. In this case the resulting XML document might not be well-formed.
       
  1089         This is the default value and QDom's behavior in Qt < 4.1.
       
  1090     \value DropInvalidChars The invalid characters should be removed from
       
  1091         the data.
       
  1092     \value ReturnNullNode The factory function should return a null node.
       
  1093 
       
  1094     \sa setInvalidDataPolicy() invalidDataPolicy()
       
  1095 */
       
  1096 
       
  1097 /*!
       
  1098    \enum QDomNode::EncodingPolicy
       
  1099    \since 4.3
       
  1100 
       
  1101    This enum specifies how QDomNode::save() determines what encoding to use
       
  1102    when serializing.
       
  1103 
       
  1104    \value EncodingFromDocument The encoding is fetched from the document.
       
  1105    \value EncodingFromTextStream The encoding is fetched from the QTextStream.
       
  1106 
       
  1107    See also the overload of the save() function that takes an EncodingPolicy.
       
  1108 */
       
  1109 
       
  1110 /*!
       
  1111     \since 4.1
       
  1112     \nonreentrant
       
  1113 
       
  1114     Returns the invalid data policy, which specifies what should be done when
       
  1115     a factory function in QDomDocument is passed invalid data.
       
  1116 
       
  1117     \sa setInvalidDataPolicy() InvalidDataPolicy
       
  1118 */
       
  1119 
       
  1120 QDomImplementation::InvalidDataPolicy QDomImplementation::invalidDataPolicy()
       
  1121 {
       
  1122     return QDomImplementationPrivate::invalidDataPolicy;
       
  1123 }
       
  1124 
       
  1125 /*!
       
  1126     \since 4.1
       
  1127     \nonreentrant
       
  1128 
       
  1129     Sets the invalid data policy, which specifies what should be done when
       
  1130     a factory function in QDomDocument is passed invalid data.
       
  1131 
       
  1132     The \a policy is set for all instances of QDomDocument which already
       
  1133     exist and which will be created in the future.
       
  1134 
       
  1135     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 0
       
  1136 
       
  1137     \sa invalidDataPolicy() InvalidDataPolicy
       
  1138 */
       
  1139 
       
  1140 void QDomImplementation::setInvalidDataPolicy(InvalidDataPolicy policy)
       
  1141 {
       
  1142     QDomImplementationPrivate::invalidDataPolicy = policy;
       
  1143 }
       
  1144 
       
  1145 /**************************************************************
       
  1146  *
       
  1147  * QDomNodeListPrivate
       
  1148  *
       
  1149  **************************************************************/
       
  1150 
       
  1151 QDomNodeListPrivate::QDomNodeListPrivate(QDomNodePrivate *n_impl)
       
  1152 {
       
  1153     ref  = 1;
       
  1154     node_impl = n_impl;
       
  1155     if (node_impl)
       
  1156         node_impl->ref.ref();
       
  1157     timestamp = 0;
       
  1158 }
       
  1159 
       
  1160 QDomNodeListPrivate::QDomNodeListPrivate(QDomNodePrivate *n_impl, const QString &name)
       
  1161 {
       
  1162     ref = 1;
       
  1163     node_impl = n_impl;
       
  1164     if (node_impl)
       
  1165         node_impl->ref.ref();
       
  1166     tagname = name;
       
  1167     timestamp = 0;
       
  1168 }
       
  1169 
       
  1170 QDomNodeListPrivate::QDomNodeListPrivate(QDomNodePrivate *n_impl, const QString &_nsURI, const QString &localName)
       
  1171 {
       
  1172     ref = 1;
       
  1173     node_impl = n_impl;
       
  1174     if (node_impl)
       
  1175         node_impl->ref.ref();
       
  1176     tagname = localName;
       
  1177     nsURI = _nsURI;
       
  1178     timestamp = 0;
       
  1179 }
       
  1180 
       
  1181 QDomNodeListPrivate::~QDomNodeListPrivate()
       
  1182 {
       
  1183     if (node_impl && !node_impl->ref.deref())
       
  1184         delete node_impl;
       
  1185 }
       
  1186 
       
  1187 bool QDomNodeListPrivate::operator==(const QDomNodeListPrivate &other) const
       
  1188 {
       
  1189     return (node_impl == other.node_impl) && (tagname == other.tagname);
       
  1190 }
       
  1191 
       
  1192 bool QDomNodeListPrivate::operator!=(const QDomNodeListPrivate &other) const
       
  1193 {
       
  1194     return (node_impl != other.node_impl) || (tagname != other.tagname);
       
  1195 }
       
  1196 
       
  1197 void QDomNodeListPrivate::createList()
       
  1198 {
       
  1199     if (!node_impl)
       
  1200         return;
       
  1201 
       
  1202     const QDomDocumentPrivate *const doc = node_impl->ownerDocument();
       
  1203     if (doc && timestamp != doc->nodeListTime)
       
  1204         timestamp = doc->nodeListTime;
       
  1205 
       
  1206     QDomNodePrivate* p = node_impl->first;
       
  1207 
       
  1208     list.clear();
       
  1209     if (tagname.isNull()) {
       
  1210         while (p) {
       
  1211             list.append(p);
       
  1212             p = p->next;
       
  1213         }
       
  1214     } else if (nsURI.isNull()) {
       
  1215         while (p && p != node_impl) {
       
  1216             if (p->isElement() && p->nodeName() == tagname) {
       
  1217                 list.append(p);
       
  1218             }
       
  1219             if (p->first)
       
  1220                 p = p->first;
       
  1221             else if (p->next)
       
  1222                 p = p->next;
       
  1223             else {
       
  1224                 p = p->parent();
       
  1225                 while (p && p != node_impl && !p->next)
       
  1226                     p = p->parent();
       
  1227                 if (p && p != node_impl)
       
  1228                     p = p->next;
       
  1229             }
       
  1230         }
       
  1231     } else {
       
  1232         while (p && p != node_impl) {
       
  1233             if (p->isElement() && p->name==tagname && p->namespaceURI==nsURI) {
       
  1234                 list.append(p);
       
  1235             }
       
  1236             if (p->first)
       
  1237                 p = p->first;
       
  1238             else if (p->next)
       
  1239                 p = p->next;
       
  1240             else {
       
  1241                 p = p->parent();
       
  1242                 while (p && p != node_impl && !p->next)
       
  1243                     p = p->parent();
       
  1244                 if (p && p != node_impl)
       
  1245                     p = p->next;
       
  1246             }
       
  1247         }
       
  1248     }
       
  1249 }
       
  1250 
       
  1251 QDomNodePrivate* QDomNodeListPrivate::item(int index)
       
  1252 {
       
  1253     if (!node_impl)
       
  1254         return 0;
       
  1255 
       
  1256     const QDomDocumentPrivate *const doc = node_impl->ownerDocument();
       
  1257     if (!doc || timestamp != doc->nodeListTime)
       
  1258         createList();
       
  1259 
       
  1260     if (index >= list.size())
       
  1261         return 0;
       
  1262 
       
  1263     return list.at(index);
       
  1264 }
       
  1265 
       
  1266 uint QDomNodeListPrivate::length() const
       
  1267 {
       
  1268     if (!node_impl)
       
  1269         return 0;
       
  1270 
       
  1271     const QDomDocumentPrivate *const doc = node_impl->ownerDocument();
       
  1272     if (!doc || timestamp != doc->nodeListTime) {
       
  1273         QDomNodeListPrivate *that = const_cast<QDomNodeListPrivate *>(this);
       
  1274         that->createList();
       
  1275     }
       
  1276 
       
  1277     return list.count();
       
  1278 }
       
  1279 
       
  1280 /**************************************************************
       
  1281  *
       
  1282  * QDomNodeList
       
  1283  *
       
  1284  **************************************************************/
       
  1285 
       
  1286 /*!
       
  1287     \class QDomNodeList
       
  1288     \reentrant
       
  1289     \brief The QDomNodeList class is a list of QDomNode objects.
       
  1290 
       
  1291     \inmodule QtXml
       
  1292     \ingroup xml-tools
       
  1293 
       
  1294     Lists can be obtained by QDomDocument::elementsByTagName() and
       
  1295     QDomNode::childNodes(). The Document Object Model (DOM) requires
       
  1296     these lists to be "live": whenever you change the underlying
       
  1297     document, the contents of the list will get updated.
       
  1298 
       
  1299     You can get a particular node from the list with item(). The
       
  1300     number of items in the list is returned by length().
       
  1301 
       
  1302     For further information about the Document Object Model see
       
  1303     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  1304     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  1305     For a more general introduction of the DOM implementation see the
       
  1306     QDomDocument documentation.
       
  1307 
       
  1308     \sa QDomNode::childNodes() QDomDocument::elementsByTagName()
       
  1309 */
       
  1310 
       
  1311 /*!
       
  1312     Creates an empty node list.
       
  1313 */
       
  1314 QDomNodeList::QDomNodeList()
       
  1315 {
       
  1316     impl = 0;
       
  1317 }
       
  1318 
       
  1319 QDomNodeList::QDomNodeList(QDomNodeListPrivate* p)
       
  1320 {
       
  1321     impl = p;
       
  1322 }
       
  1323 
       
  1324 /*!
       
  1325     Constructs a copy of \a n.
       
  1326 */
       
  1327 QDomNodeList::QDomNodeList(const QDomNodeList& n)
       
  1328 {
       
  1329     impl = n.impl;
       
  1330     if (impl)
       
  1331         impl->ref.ref();
       
  1332 }
       
  1333 
       
  1334 /*!
       
  1335     Assigns \a n to this node list.
       
  1336 */
       
  1337 QDomNodeList& QDomNodeList::operator=(const QDomNodeList &n)
       
  1338 {
       
  1339     if (n.impl)
       
  1340         n.impl->ref.ref();
       
  1341     if (impl && !impl->ref.deref())
       
  1342         delete impl;
       
  1343     impl = n.impl;
       
  1344     return *this;
       
  1345 }
       
  1346 
       
  1347 /*!
       
  1348     Returns true if the node list \a n and this node list are equal;
       
  1349     otherwise returns false.
       
  1350 */
       
  1351 bool QDomNodeList::operator==(const QDomNodeList &n) const
       
  1352 {
       
  1353     if (impl == n.impl)
       
  1354         return true;
       
  1355     if (!impl || !n.impl)
       
  1356         return false;
       
  1357     return (*impl == *n.impl);
       
  1358 }
       
  1359 
       
  1360 /*!
       
  1361     Returns true the node list \a n and this node list are not equal;
       
  1362     otherwise returns false.
       
  1363 */
       
  1364 bool QDomNodeList::operator!=(const QDomNodeList &n) const
       
  1365 {
       
  1366     return !operator==(n);
       
  1367 }
       
  1368 
       
  1369 /*!
       
  1370     Destroys the object and frees its resources.
       
  1371 */
       
  1372 QDomNodeList::~QDomNodeList()
       
  1373 {
       
  1374     if (impl && !impl->ref.deref())
       
  1375         delete impl;
       
  1376 }
       
  1377 
       
  1378 /*!
       
  1379     Returns the node at position \a index.
       
  1380 
       
  1381     If \a index is negative or if \a index >= length() then a null
       
  1382     node is returned (i.e. a node for which QDomNode::isNull() returns
       
  1383     true).
       
  1384 
       
  1385     \sa length()
       
  1386 */
       
  1387 QDomNode QDomNodeList::item(int index) const
       
  1388 {
       
  1389     if (!impl)
       
  1390         return QDomNode();
       
  1391 
       
  1392     return QDomNode(impl->item(index));
       
  1393 }
       
  1394 
       
  1395 /*!
       
  1396     Returns the number of nodes in the list.
       
  1397 */
       
  1398 uint QDomNodeList::length() const
       
  1399 {
       
  1400     if (!impl)
       
  1401         return 0;
       
  1402     return impl->length();
       
  1403 }
       
  1404 
       
  1405 /*!
       
  1406     \fn bool QDomNodeList::isEmpty() const
       
  1407 
       
  1408     Returns true if the list contains no items; otherwise returns false.
       
  1409     This function is provided for Qt API consistency.
       
  1410 */
       
  1411 
       
  1412 /*!
       
  1413     \fn int QDomNodeList::count() const
       
  1414 
       
  1415     This function is provided for Qt API consistency. It is equivalent to length().
       
  1416 */
       
  1417 
       
  1418 /*!
       
  1419     \fn int QDomNodeList::size() const
       
  1420 
       
  1421     This function is provided for Qt API consistency. It is equivalent to length().
       
  1422 */
       
  1423 
       
  1424 /*!
       
  1425     \fn QDomNode QDomNodeList::at(int index) const
       
  1426 
       
  1427     This function is provided for Qt API consistency. It is equivalent
       
  1428     to item().
       
  1429 
       
  1430     If \a index is negative or if \a index >= length() then a null
       
  1431     node is returned (i.e. a node for which QDomNode::isNull() returns
       
  1432     true).
       
  1433 */
       
  1434 
       
  1435 /**************************************************************
       
  1436  *
       
  1437  * QDomNodePrivate
       
  1438  *
       
  1439  **************************************************************/
       
  1440 
       
  1441 inline void QDomNodePrivate::setOwnerDocument(QDomDocumentPrivate *doc)
       
  1442 {
       
  1443     ownerNode = doc;
       
  1444     hasParent = false;
       
  1445 }
       
  1446 
       
  1447 QDomNodePrivate::QDomNodePrivate(QDomDocumentPrivate *doc, QDomNodePrivate *par)
       
  1448 {
       
  1449     ref = 1;
       
  1450     if (par)
       
  1451         setParent(par);
       
  1452     else
       
  1453         setOwnerDocument(doc);
       
  1454     prev = 0;
       
  1455     next = 0;
       
  1456     first = 0;
       
  1457     last = 0;
       
  1458     createdWithDom1Interface = true;
       
  1459     lineNumber = -1;
       
  1460     columnNumber = -1;
       
  1461 }
       
  1462 
       
  1463 QDomNodePrivate::QDomNodePrivate(QDomNodePrivate *n, bool deep)
       
  1464 {
       
  1465     ref = 1;
       
  1466     setOwnerDocument(n->ownerDocument());
       
  1467     prev = 0;
       
  1468     next = 0;
       
  1469     first = 0;
       
  1470     last = 0;
       
  1471 
       
  1472     name = n->name;
       
  1473     value = n->value;
       
  1474     prefix = n->prefix;
       
  1475     namespaceURI = n->namespaceURI;
       
  1476     createdWithDom1Interface = n->createdWithDom1Interface;
       
  1477     lineNumber = -1;
       
  1478     columnNumber = -1;
       
  1479 
       
  1480     if (!deep)
       
  1481         return;
       
  1482 
       
  1483     for (QDomNodePrivate* x = n->first; x; x = x->next)
       
  1484         appendChild(x->cloneNode(true));
       
  1485 }
       
  1486 
       
  1487 QDomNodePrivate::~QDomNodePrivate()
       
  1488 {
       
  1489     QDomNodePrivate* p = first;
       
  1490     QDomNodePrivate* n;
       
  1491 
       
  1492     while (p) {
       
  1493         n = p->next;
       
  1494         if (!p->ref.deref())
       
  1495             delete p;
       
  1496         else
       
  1497             p->setNoParent();
       
  1498         p = n;
       
  1499     }
       
  1500     first = 0;
       
  1501     last = 0;
       
  1502 }
       
  1503 
       
  1504 void QDomNodePrivate::clear()
       
  1505 {
       
  1506     QDomNodePrivate* p = first;
       
  1507     QDomNodePrivate* n;
       
  1508 
       
  1509     while (p) {
       
  1510         n = p->next;
       
  1511         if (!p->ref.deref())
       
  1512             delete p;
       
  1513         p = n;
       
  1514     }
       
  1515     first = 0;
       
  1516     last = 0;
       
  1517 }
       
  1518 
       
  1519 QDomNodePrivate* QDomNodePrivate::namedItem(const QString &n)
       
  1520 {
       
  1521     QDomNodePrivate* p = first;
       
  1522     while (p) {
       
  1523         if (p->nodeName() == n)
       
  1524             return p;
       
  1525         p = p->next;
       
  1526     }
       
  1527     return 0;
       
  1528 }
       
  1529 
       
  1530 
       
  1531 QDomNodePrivate* QDomNodePrivate::insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild)
       
  1532 {
       
  1533     // Error check
       
  1534     if (!newChild)
       
  1535         return 0;
       
  1536 
       
  1537     // Error check
       
  1538     if (newChild == refChild)
       
  1539         return 0;
       
  1540 
       
  1541     // Error check
       
  1542     if (refChild && refChild->parent() != this)
       
  1543         return 0;
       
  1544 
       
  1545     // "mark lists as dirty"
       
  1546     QDomDocumentPrivate *const doc = ownerDocument();
       
  1547     if(doc)
       
  1548         doc->nodeListTime++;
       
  1549 
       
  1550     // Special handling for inserting a fragment. We just insert
       
  1551     // all elements of the fragment instead of the fragment itself.
       
  1552     if (newChild->isDocumentFragment()) {
       
  1553         // Fragment is empty ?
       
  1554         if (newChild->first == 0)
       
  1555             return newChild;
       
  1556 
       
  1557         // New parent
       
  1558         QDomNodePrivate* n = newChild->first;
       
  1559         while (n)  {
       
  1560             n->setParent(this);
       
  1561             n = n->next;
       
  1562         }
       
  1563 
       
  1564         // Insert at the beginning ?
       
  1565         if (!refChild || refChild->prev == 0) {
       
  1566             if (first)
       
  1567                 first->prev = newChild->last;
       
  1568             newChild->last->next = first;
       
  1569             if (!last)
       
  1570                 last = newChild->last;
       
  1571             first = newChild->first;
       
  1572         } else {
       
  1573             // Insert in the middle
       
  1574             newChild->last->next = refChild;
       
  1575             newChild->first->prev = refChild->prev;
       
  1576             refChild->prev->next = newChild->first;
       
  1577             refChild->prev = newChild->last;
       
  1578         }
       
  1579 
       
  1580         // No need to increase the reference since QDomDocumentFragment
       
  1581         // does not decrease the reference.
       
  1582 
       
  1583         // Remove the nodes from the fragment
       
  1584         newChild->first = 0;
       
  1585         newChild->last = 0;
       
  1586         return newChild;
       
  1587     }
       
  1588 
       
  1589     // No more errors can occur now, so we take
       
  1590     // ownership of the node.
       
  1591     newChild->ref.ref();
       
  1592 
       
  1593     if (newChild->parent())
       
  1594         newChild->parent()->removeChild(newChild);
       
  1595 
       
  1596     newChild->setParent(this);
       
  1597 
       
  1598     if (!refChild) {
       
  1599         if (first)
       
  1600             first->prev = newChild;
       
  1601         newChild->next = first;
       
  1602         if (!last)
       
  1603             last = newChild;
       
  1604         first = newChild;
       
  1605         return newChild;
       
  1606     }
       
  1607 
       
  1608     if (refChild->prev == 0) {
       
  1609         if (first)
       
  1610             first->prev = newChild;
       
  1611         newChild->next = first;
       
  1612         if (!last)
       
  1613             last = newChild;
       
  1614         first = newChild;
       
  1615         return newChild;
       
  1616     }
       
  1617 
       
  1618     newChild->next = refChild;
       
  1619     newChild->prev = refChild->prev;
       
  1620     refChild->prev->next = newChild;
       
  1621     refChild->prev = newChild;
       
  1622 
       
  1623     return newChild;
       
  1624 }
       
  1625 
       
  1626 QDomNodePrivate* QDomNodePrivate::insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild)
       
  1627 {
       
  1628     // Error check
       
  1629     if (!newChild)
       
  1630         return 0;
       
  1631 
       
  1632     // Error check
       
  1633     if (newChild == refChild)
       
  1634         return 0;
       
  1635 
       
  1636     // Error check
       
  1637     if (refChild && refChild->parent() != this)
       
  1638         return 0;
       
  1639 
       
  1640     // "mark lists as dirty"
       
  1641     QDomDocumentPrivate *const doc = ownerDocument();
       
  1642     if(doc)
       
  1643         doc->nodeListTime++;
       
  1644 
       
  1645     // Special handling for inserting a fragment. We just insert
       
  1646     // all elements of the fragment instead of the fragment itself.
       
  1647     if (newChild->isDocumentFragment()) {
       
  1648         // Fragment is empty ?
       
  1649         if (newChild->first == 0)
       
  1650             return newChild;
       
  1651 
       
  1652         // New parent
       
  1653         QDomNodePrivate* n = newChild->first;
       
  1654         while (n) {
       
  1655             n->setParent(this);
       
  1656             n = n->next;
       
  1657         }
       
  1658 
       
  1659         // Insert at the end
       
  1660         if (!refChild || refChild->next == 0) {
       
  1661             if (last)
       
  1662                 last->next = newChild->first;
       
  1663             newChild->first->prev = last;
       
  1664             if (!first)
       
  1665                 first = newChild->first;
       
  1666             last = newChild->last;
       
  1667         } else { // Insert in the middle
       
  1668             newChild->first->prev = refChild;
       
  1669             newChild->last->next = refChild->next;
       
  1670             refChild->next->prev = newChild->last;
       
  1671             refChild->next = newChild->first;
       
  1672         }
       
  1673 
       
  1674         // No need to increase the reference since QDomDocumentFragment
       
  1675         // does not decrease the reference.
       
  1676 
       
  1677         // Remove the nodes from the fragment
       
  1678         newChild->first = 0;
       
  1679         newChild->last = 0;
       
  1680         return newChild;
       
  1681     }
       
  1682 
       
  1683     // Release new node from its current parent
       
  1684     if (newChild->parent())
       
  1685         newChild->parent()->removeChild(newChild);
       
  1686 
       
  1687     // No more errors can occur now, so we take
       
  1688     // ownership of the node
       
  1689     newChild->ref.ref();
       
  1690 
       
  1691     newChild->setParent(this);
       
  1692 
       
  1693     // Insert at the end
       
  1694     if (!refChild) {
       
  1695         if (last)
       
  1696             last->next = newChild;
       
  1697         newChild->prev = last;
       
  1698         if (!first)
       
  1699             first = newChild;
       
  1700         last = newChild;
       
  1701         return newChild;
       
  1702     }
       
  1703 
       
  1704     if (refChild->next == 0) {
       
  1705         if (last)
       
  1706             last->next = newChild;
       
  1707         newChild->prev = last;
       
  1708         if (!first)
       
  1709             first = newChild;
       
  1710         last = newChild;
       
  1711         return newChild;
       
  1712     }
       
  1713 
       
  1714     newChild->prev = refChild;
       
  1715     newChild->next = refChild->next;
       
  1716     refChild->next->prev = newChild;
       
  1717     refChild->next = newChild;
       
  1718 
       
  1719     return newChild;
       
  1720 }
       
  1721 
       
  1722 QDomNodePrivate* QDomNodePrivate::replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild)
       
  1723 {
       
  1724     if (!newChild || !oldChild)
       
  1725         return 0;
       
  1726     if (oldChild->parent() != this)
       
  1727         return 0;
       
  1728     if (newChild == oldChild)
       
  1729         return 0;
       
  1730 
       
  1731     // mark lists as dirty
       
  1732     QDomDocumentPrivate *const doc = ownerDocument();
       
  1733     if(doc)
       
  1734         doc->nodeListTime++;
       
  1735 
       
  1736     // Special handling for inserting a fragment. We just insert
       
  1737     // all elements of the fragment instead of the fragment itself.
       
  1738     if (newChild->isDocumentFragment()) {
       
  1739         // Fragment is empty ?
       
  1740         if (newChild->first == 0)
       
  1741             return newChild;
       
  1742 
       
  1743         // New parent
       
  1744         QDomNodePrivate* n = newChild->first;
       
  1745         while (n) {
       
  1746             n->setParent(this);
       
  1747             n = n->next;
       
  1748         }
       
  1749 
       
  1750 
       
  1751         if (oldChild->next)
       
  1752             oldChild->next->prev = newChild->last;
       
  1753         if (oldChild->prev)
       
  1754             oldChild->prev->next = newChild->first;
       
  1755 
       
  1756         newChild->last->next = oldChild->next;
       
  1757         newChild->first->prev = oldChild->prev;
       
  1758 
       
  1759         if (first == oldChild)
       
  1760             first = newChild->first;
       
  1761         if (last == oldChild)
       
  1762             last = newChild->last;
       
  1763 
       
  1764         oldChild->setNoParent();
       
  1765         oldChild->next = 0;
       
  1766         oldChild->prev = 0;
       
  1767 
       
  1768         // No need to increase the reference since QDomDocumentFragment
       
  1769         // does not decrease the reference.
       
  1770 
       
  1771         // Remove the nodes from the fragment
       
  1772         newChild->first = 0;
       
  1773         newChild->last = 0;
       
  1774 
       
  1775         // We are no longer interested in the old node
       
  1776         if (oldChild)
       
  1777             oldChild->ref.deref();
       
  1778 
       
  1779         return oldChild;
       
  1780     }
       
  1781 
       
  1782     // No more errors can occur now, so we take
       
  1783     // ownership of the node
       
  1784     newChild->ref.ref();
       
  1785 
       
  1786     // Release new node from its current parent
       
  1787     if (newChild->parent())
       
  1788         newChild->parent()->removeChild(newChild);
       
  1789 
       
  1790     newChild->setParent(this);
       
  1791 
       
  1792     if (oldChild->next)
       
  1793         oldChild->next->prev = newChild;
       
  1794     if (oldChild->prev)
       
  1795         oldChild->prev->next = newChild;
       
  1796 
       
  1797     newChild->next = oldChild->next;
       
  1798     newChild->prev = oldChild->prev;
       
  1799 
       
  1800     if (first == oldChild)
       
  1801         first = newChild;
       
  1802     if (last == oldChild)
       
  1803         last = newChild;
       
  1804 
       
  1805     oldChild->setNoParent();
       
  1806     oldChild->next = 0;
       
  1807     oldChild->prev = 0;
       
  1808 
       
  1809     // We are no longer interested in the old node
       
  1810     if (oldChild)
       
  1811         oldChild->ref.deref();
       
  1812 
       
  1813     return oldChild;
       
  1814 }
       
  1815 
       
  1816 QDomNodePrivate* QDomNodePrivate::removeChild(QDomNodePrivate* oldChild)
       
  1817 {
       
  1818     // Error check
       
  1819     if (oldChild->parent() != this)
       
  1820         return 0;
       
  1821 
       
  1822     // "mark lists as dirty"
       
  1823     QDomDocumentPrivate *const doc = ownerDocument();
       
  1824     if(doc)
       
  1825         doc->nodeListTime++;
       
  1826 
       
  1827     // Perhaps oldChild was just created with "createElement" or that. In this case
       
  1828     // its parent is QDomDocument but it is not part of the documents child list.
       
  1829     if (oldChild->next == 0 && oldChild->prev == 0 && first != oldChild)
       
  1830         return 0;
       
  1831 
       
  1832     if (oldChild->next)
       
  1833         oldChild->next->prev = oldChild->prev;
       
  1834     if (oldChild->prev)
       
  1835         oldChild->prev->next = oldChild->next;
       
  1836 
       
  1837     if (last == oldChild)
       
  1838         last = oldChild->prev;
       
  1839     if (first == oldChild)
       
  1840         first = oldChild->next;
       
  1841 
       
  1842     oldChild->setNoParent();
       
  1843     oldChild->next = 0;
       
  1844     oldChild->prev = 0;
       
  1845 
       
  1846     // We are no longer interested in the old node
       
  1847     oldChild->ref.deref();
       
  1848 
       
  1849     return oldChild;
       
  1850 }
       
  1851 
       
  1852 QDomNodePrivate* QDomNodePrivate::appendChild(QDomNodePrivate* newChild)
       
  1853 {
       
  1854     // No reference manipulation needed. Done in insertAfter.
       
  1855     return insertAfter(newChild, 0);
       
  1856 }
       
  1857 
       
  1858 QDomDocumentPrivate* QDomNodePrivate::ownerDocument()
       
  1859 {
       
  1860     QDomNodePrivate* p = this;
       
  1861     while (p && !p->isDocument()) {
       
  1862         if (!p->hasParent)
       
  1863             return (QDomDocumentPrivate*)p->ownerNode;
       
  1864         p = p->parent();
       
  1865     }
       
  1866 
       
  1867     return static_cast<QDomDocumentPrivate *>(p);
       
  1868 }
       
  1869 
       
  1870 QDomNodePrivate* QDomNodePrivate::cloneNode(bool deep)
       
  1871 {
       
  1872     QDomNodePrivate* p = new QDomNodePrivate(this, deep);
       
  1873     // We are not interested in this node
       
  1874     p->ref.deref();
       
  1875     return p;
       
  1876 }
       
  1877 
       
  1878 static void qNormalizeNode(QDomNodePrivate* n)
       
  1879 {
       
  1880     QDomNodePrivate* p = n->first;
       
  1881     QDomTextPrivate* t = 0;
       
  1882 
       
  1883     while (p) {
       
  1884         if (p->isText()) {
       
  1885             if (t) {
       
  1886                 QDomNodePrivate* tmp = p->next;
       
  1887                 t->appendData(p->nodeValue());
       
  1888                 n->removeChild(p);
       
  1889                 p = tmp;
       
  1890             } else {
       
  1891                 t = (QDomTextPrivate*)p;
       
  1892                 p = p->next;
       
  1893             }
       
  1894         } else {
       
  1895             p = p->next;
       
  1896             t = 0;
       
  1897         }
       
  1898     }
       
  1899 }
       
  1900 void QDomNodePrivate::normalize()
       
  1901 {
       
  1902     // ### This one has moved from QDomElementPrivate to this position. It is
       
  1903     // not tested.
       
  1904     qNormalizeNode(this);
       
  1905 }
       
  1906 
       
  1907 /*! \internal
       
  1908   \a depth is used for indentation, it seems.
       
  1909  */
       
  1910 void QDomNodePrivate::save(QTextStream& s, int depth, int indent) const
       
  1911 {
       
  1912     const QDomNodePrivate* n = first;
       
  1913     while (n) {
       
  1914         n->save(s, depth, indent);
       
  1915         n = n->next;
       
  1916     }
       
  1917 }
       
  1918 
       
  1919 void QDomNodePrivate::setLocation(int lineNumber, int columnNumber)
       
  1920 {
       
  1921     this->lineNumber = lineNumber;
       
  1922     this->columnNumber = columnNumber;
       
  1923 }
       
  1924 
       
  1925 /**************************************************************
       
  1926  *
       
  1927  * QDomNode
       
  1928  *
       
  1929  **************************************************************/
       
  1930 
       
  1931 #define IMPL ((QDomNodePrivate*)impl)
       
  1932 
       
  1933 /*!
       
  1934     \class QDomNode
       
  1935     \reentrant
       
  1936     \brief The QDomNode class is the base class for all the nodes in a DOM tree.
       
  1937 
       
  1938     \inmodule QtXml
       
  1939     \ingroup xml-tools
       
  1940 
       
  1941 
       
  1942     Many functions in the DOM return a QDomNode.
       
  1943 
       
  1944     You can find out the type of a node using isAttr(),
       
  1945     isCDATASection(), isDocumentFragment(), isDocument(),
       
  1946     isDocumentType(), isElement(), isEntityReference(), isText(),
       
  1947     isEntity(), isNotation(), isProcessingInstruction(),
       
  1948     isCharacterData() and isComment().
       
  1949 
       
  1950     A QDomNode can be converted into one of its subclasses using
       
  1951     toAttr(), toCDATASection(), toDocumentFragment(), toDocument(),
       
  1952     toDocumentType(), toElement(), toEntityReference(), toText(),
       
  1953     toEntity(), toNotation(), toProcessingInstruction(),
       
  1954     toCharacterData() or toComment(). You can convert a node to a null
       
  1955     node with clear().
       
  1956 
       
  1957     Copies of the QDomNode class share their data using explicit
       
  1958     sharing. This means that modifying one node will change all
       
  1959     copies. This is especially useful in combination with functions
       
  1960     which return a QDomNode, e.g. firstChild(). You can make an
       
  1961     independent (deep) copy of the node with cloneNode().
       
  1962 
       
  1963     A QDomNode can be null, much like a null pointer. Creating a copy
       
  1964     of a null node results in another null node. It is not
       
  1965     possible to modify a null node, but it is possible to assign another,
       
  1966     possibly non-null node to it. In this case, the copy of the null node
       
  1967     will remain null. You can check if a QDomNode is null by calling isNull().
       
  1968     The empty constructor of a QDomNode (or any of the derived classes) creates
       
  1969     a null node.
       
  1970 
       
  1971     Nodes are inserted with insertBefore(), insertAfter() or
       
  1972     appendChild(). You can replace one node with another using
       
  1973     replaceChild() and remove a node with removeChild().
       
  1974 
       
  1975     To traverse nodes use firstChild() to get a node's first child (if
       
  1976     any), and nextSibling() to traverse. QDomNode also provides
       
  1977     lastChild(), previousSibling() and parentNode(). To find the first
       
  1978     child node with a particular node name use namedItem().
       
  1979 
       
  1980     To find out if a node has children use hasChildNodes() and to get
       
  1981     a list of all of a node's children use childNodes().
       
  1982 
       
  1983     The node's name and value (the meaning of which varies depending
       
  1984     on its type) is returned by nodeName() and nodeValue()
       
  1985     respectively. The node's type is returned by nodeType(). The
       
  1986     node's value can be set with setNodeValue().
       
  1987 
       
  1988     The document to which the node belongs is returned by
       
  1989     ownerDocument().
       
  1990 
       
  1991     Adjacent QDomText nodes can be merged into a single node with
       
  1992     normalize().
       
  1993 
       
  1994     \l QDomElement nodes have attributes which can be retrieved with
       
  1995     attributes().
       
  1996 
       
  1997     QDomElement and QDomAttr nodes can have namespaces which can be
       
  1998     retrieved with namespaceURI(). Their local name is retrieved with
       
  1999     localName(), and their prefix with prefix(). The prefix can be set
       
  2000     with setPrefix().
       
  2001 
       
  2002     You can write the XML representation of the node to a text stream
       
  2003     with save().
       
  2004 
       
  2005     The following example looks for the first element in an XML document and
       
  2006     prints the names of all the elements that are its direct children.
       
  2007     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 1
       
  2008 
       
  2009     For further information about the Document Object Model see
       
  2010     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  2011     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  2012     For a more general introduction of the DOM implementation see the
       
  2013     QDomDocument documentation.
       
  2014 */
       
  2015 
       
  2016 /*!
       
  2017     Constructs a \link isNull() null\endlink node.
       
  2018 */
       
  2019 QDomNode::QDomNode()
       
  2020 {
       
  2021     impl = 0;
       
  2022 }
       
  2023 
       
  2024 /*!
       
  2025     Constructs a copy of \a n.
       
  2026 
       
  2027     The data of the copy is shared (shallow copy): modifying one node
       
  2028     will also change the other. If you want to make a deep copy, use
       
  2029     cloneNode().
       
  2030 */
       
  2031 QDomNode::QDomNode(const QDomNode &n)
       
  2032 {
       
  2033     impl = n.impl;
       
  2034     if (impl)
       
  2035         impl->ref.ref();
       
  2036 }
       
  2037 
       
  2038 /*!  \internal
       
  2039   Constructs a new node for the data \a n.
       
  2040 */
       
  2041 QDomNode::QDomNode(QDomNodePrivate *n)
       
  2042 {
       
  2043     impl = n;
       
  2044     if (impl)
       
  2045         impl->ref.ref();
       
  2046 }
       
  2047 
       
  2048 /*!
       
  2049     Assigns a copy of \a n to this DOM node.
       
  2050 
       
  2051     The data of the copy is shared (shallow copy): modifying one node
       
  2052     will also change the other. If you want to make a deep copy, use
       
  2053     cloneNode().
       
  2054 */
       
  2055 QDomNode& QDomNode::operator=(const QDomNode &n)
       
  2056 {
       
  2057     if (n.impl)
       
  2058         n.impl->ref.ref();
       
  2059     if (impl && !impl->ref.deref())
       
  2060         delete impl;
       
  2061     impl = n.impl;
       
  2062     return *this;
       
  2063 }
       
  2064 
       
  2065 /*!
       
  2066     Returns true if \a n and this DOM node are equal; otherwise
       
  2067     returns false.
       
  2068 
       
  2069     Any instance of QDomNode acts as a reference to an underlying data
       
  2070     structure in QDomDocument. The test for equality checks if the two
       
  2071     references point to the same underlying node. For example:
       
  2072 
       
  2073     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 2
       
  2074 
       
  2075     The two nodes (QDomElement is a QDomNode subclass) both refer to
       
  2076     the document's root element, and \c {element1 == element2} will
       
  2077     return true. On the other hand:
       
  2078 
       
  2079     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 3
       
  2080 
       
  2081     Even though both nodes are empty elements carrying the same name,
       
  2082     \c {element3 == element4} will return false because they refer to
       
  2083     two different nodes in the underlying data structure.
       
  2084 */
       
  2085 bool QDomNode::operator== (const QDomNode& n) const
       
  2086 {
       
  2087     return (impl == n.impl);
       
  2088 }
       
  2089 
       
  2090 /*!
       
  2091     Returns true if \a n and this DOM node are not equal; otherwise
       
  2092     returns false.
       
  2093 */
       
  2094 bool QDomNode::operator!= (const QDomNode& n) const
       
  2095 {
       
  2096     return (impl != n.impl);
       
  2097 }
       
  2098 
       
  2099 /*!
       
  2100     Destroys the object and frees its resources.
       
  2101 */
       
  2102 QDomNode::~QDomNode()
       
  2103 {
       
  2104     if (impl && !impl->ref.deref())
       
  2105         delete impl;
       
  2106 }
       
  2107 
       
  2108 /*!
       
  2109     Returns the name of the node.
       
  2110 
       
  2111     The meaning of the name depends on the subclass:
       
  2112 
       
  2113     \table
       
  2114     \header \i Name \i Meaning
       
  2115     \row \i QDomAttr \i The name of the attribute
       
  2116     \row \i QDomCDATASection \i The string "#cdata-section"
       
  2117     \row \i QDomComment \i The string "#comment"
       
  2118     \row \i QDomDocument \i The string "#document"
       
  2119     \row \i QDomDocumentFragment \i The string "#document-fragment"
       
  2120     \row \i QDomDocumentType \i The name of the document type
       
  2121     \row \i QDomElement \i The tag name
       
  2122     \row \i QDomEntity \i The name of the entity
       
  2123     \row \i QDomEntityReference \i The name of the referenced entity
       
  2124     \row \i QDomNotation \i The name of the notation
       
  2125     \row \i QDomProcessingInstruction \i The target of the processing instruction
       
  2126     \row \i QDomText \i The string "#text"
       
  2127     \endtable
       
  2128 
       
  2129     \bold{Note:} This function does not take the presence of namespaces into account
       
  2130     when processing the names of element and attribute nodes. As a result, the
       
  2131     returned name can contain any namespace prefix that may be present.
       
  2132     To obtain the node name of an element or attribute, use localName(); to
       
  2133     obtain the namespace prefix, use namespaceURI().
       
  2134 
       
  2135     \sa nodeValue()
       
  2136 */
       
  2137 QString QDomNode::nodeName() const
       
  2138 {
       
  2139     if (!impl)
       
  2140         return QString();
       
  2141 
       
  2142     if (!IMPL->prefix.isEmpty())
       
  2143         return IMPL->prefix + QLatin1Char(':') + IMPL->name;
       
  2144     return IMPL->name;
       
  2145 }
       
  2146 
       
  2147 /*!
       
  2148     Returns the value of the node.
       
  2149 
       
  2150     The meaning of the value depends on the subclass:
       
  2151     \table
       
  2152     \header \i Name \i Meaning
       
  2153     \row \i QDomAttr \i The attribute value
       
  2154     \row \i QDomCDATASection \i The content of the CDATA section
       
  2155     \row \i QDomComment \i The comment
       
  2156     \row \i QDomProcessingInstruction \i The data of the processing instruction
       
  2157     \row \i QDomText \i The text
       
  2158     \endtable
       
  2159 
       
  2160     All the other subclasses do not have a node value and will return
       
  2161     an empty string.
       
  2162 
       
  2163     \sa setNodeValue() nodeName()
       
  2164 */
       
  2165 QString QDomNode::nodeValue() const
       
  2166 {
       
  2167     if (!impl)
       
  2168         return QString();
       
  2169     return IMPL->value;
       
  2170 }
       
  2171 
       
  2172 /*!
       
  2173     Sets the node's value to \a v.
       
  2174 
       
  2175     \sa nodeValue()
       
  2176 */
       
  2177 void QDomNode::setNodeValue(const QString& v)
       
  2178 {
       
  2179     if (!impl)
       
  2180         return;
       
  2181     IMPL->setNodeValue(v);
       
  2182 }
       
  2183 
       
  2184 /*!
       
  2185     \enum QDomNode::NodeType
       
  2186 
       
  2187     This enum defines the type of the node:
       
  2188     \value ElementNode
       
  2189     \value AttributeNode
       
  2190     \value TextNode
       
  2191     \value CDATASectionNode
       
  2192     \value EntityReferenceNode
       
  2193     \value EntityNode
       
  2194     \value ProcessingInstructionNode
       
  2195     \value CommentNode
       
  2196     \value DocumentNode
       
  2197     \value DocumentTypeNode
       
  2198     \value DocumentFragmentNode
       
  2199     \value NotationNode
       
  2200     \value BaseNode  A QDomNode object, i.e. not a QDomNode subclass.
       
  2201     \value CharacterDataNode
       
  2202 */
       
  2203 
       
  2204 /*!
       
  2205     Returns the type of the node.
       
  2206 
       
  2207     \sa toAttr(), toCDATASection(), toDocumentFragment(),
       
  2208     toDocument() toDocumentType(), toElement(), toEntityReference(),
       
  2209     toText(), toEntity() toNotation(), toProcessingInstruction(),
       
  2210     toCharacterData(), toComment()
       
  2211 */
       
  2212 QDomNode::NodeType QDomNode::nodeType() const
       
  2213 {
       
  2214     if (!impl)
       
  2215         return QDomNode::BaseNode;
       
  2216     return IMPL->nodeType();
       
  2217 }
       
  2218 
       
  2219 /*!
       
  2220     Returns the parent node. If this node has no parent, a null node
       
  2221     is returned (i.e. a node for which isNull() returns true).
       
  2222 */
       
  2223 QDomNode QDomNode::parentNode() const
       
  2224 {
       
  2225     if (!impl)
       
  2226         return QDomNode();
       
  2227     return QDomNode(IMPL->parent());
       
  2228 }
       
  2229 
       
  2230 /*!
       
  2231     Returns a list of all direct child nodes.
       
  2232 
       
  2233     Most often you will call this function on a QDomElement object.
       
  2234 
       
  2235     For example, if the XML document looks like this:
       
  2236     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 4
       
  2237     Then the list of child nodes for the "body"-element will contain
       
  2238     the node created by the &lt;h1&gt; tag and the node created by the
       
  2239     &lt;p&gt; tag.
       
  2240 
       
  2241     The nodes in the list are not copied; so changing the nodes in the
       
  2242     list will also change the children of this node.
       
  2243 
       
  2244     \sa firstChild() lastChild()
       
  2245 */
       
  2246 QDomNodeList QDomNode::childNodes() const
       
  2247 {
       
  2248     if (!impl)
       
  2249         return QDomNodeList();
       
  2250     return QDomNodeList(new QDomNodeListPrivate(impl));
       
  2251 }
       
  2252 
       
  2253 /*!
       
  2254     Returns the first child of the node. If there is no child node, a
       
  2255     \link isNull() null node\endlink is returned. Changing the
       
  2256     returned node will also change the node in the document tree.
       
  2257 
       
  2258     \sa lastChild() childNodes()
       
  2259 */
       
  2260 QDomNode QDomNode::firstChild() const
       
  2261 {
       
  2262     if (!impl)
       
  2263         return QDomNode();
       
  2264     return QDomNode(IMPL->first);
       
  2265 }
       
  2266 
       
  2267 /*!
       
  2268     Returns the last child of the node. If there is no child node, a
       
  2269     \link isNull() null node\endlink is returned. Changing the
       
  2270     returned node will also change the node in the document tree.
       
  2271 
       
  2272     \sa firstChild() childNodes()
       
  2273 */
       
  2274 QDomNode QDomNode::lastChild() const
       
  2275 {
       
  2276     if (!impl)
       
  2277         return QDomNode();
       
  2278     return QDomNode(IMPL->last);
       
  2279 }
       
  2280 
       
  2281 /*!
       
  2282     Returns the previous sibling in the document tree. Changing the
       
  2283     returned node will also change the node in the document tree.
       
  2284 
       
  2285     For example, if you have XML like this:
       
  2286     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 5
       
  2287     and this QDomNode represents the &lt;p&gt; tag, previousSibling()
       
  2288     will return the node representing the &lt;h1&gt; tag.
       
  2289 
       
  2290     \sa nextSibling()
       
  2291 */
       
  2292 QDomNode QDomNode::previousSibling() const
       
  2293 {
       
  2294     if (!impl)
       
  2295         return QDomNode();
       
  2296     return QDomNode(IMPL->prev);
       
  2297 }
       
  2298 
       
  2299 /*!
       
  2300     Returns the next sibling in the document tree. Changing the
       
  2301     returned node will also change the node in the document tree.
       
  2302 
       
  2303     If you have XML like this:
       
  2304     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 6
       
  2305     and this QDomNode represents the <p> tag, nextSibling() will
       
  2306     return the node representing the <h2> tag.
       
  2307 
       
  2308     \sa previousSibling()
       
  2309 */
       
  2310 QDomNode QDomNode::nextSibling() const
       
  2311 {
       
  2312     if (!impl)
       
  2313         return QDomNode();
       
  2314     return QDomNode(IMPL->next);
       
  2315 }
       
  2316 
       
  2317 
       
  2318 // ###### don't think this is part of the DOM and
       
  2319 /*!
       
  2320     Returns a named node map of all attributes. Attributes are only
       
  2321     provided for \l{QDomElement}s.
       
  2322 
       
  2323     Changing the attributes in the map will also change the attributes
       
  2324     of this QDomNode.
       
  2325 */
       
  2326 QDomNamedNodeMap QDomNode::attributes() const
       
  2327 {
       
  2328     if (!impl || !impl->isElement())
       
  2329         return QDomNamedNodeMap();
       
  2330 
       
  2331     return QDomNamedNodeMap(static_cast<QDomElementPrivate *>(impl)->attributes());
       
  2332 }
       
  2333 
       
  2334 /*!
       
  2335     Returns the document to which this node belongs.
       
  2336 */
       
  2337 QDomDocument QDomNode::ownerDocument() const
       
  2338 {
       
  2339     if (!impl)
       
  2340         return QDomDocument();
       
  2341     return QDomDocument(IMPL->ownerDocument());
       
  2342 }
       
  2343 
       
  2344 /*!
       
  2345     Creates a deep (not shallow) copy of the QDomNode.
       
  2346 
       
  2347     If \a deep is true, then the cloning is done recursively which
       
  2348     means that all the node's children are deep copied too. If \a deep
       
  2349     is false only the node itself is copied and the copy will have no
       
  2350     child nodes.
       
  2351 */
       
  2352 QDomNode QDomNode::cloneNode(bool deep) const
       
  2353 {
       
  2354     if (!impl)
       
  2355         return QDomNode();
       
  2356     return QDomNode(IMPL->cloneNode(deep));
       
  2357 }
       
  2358 
       
  2359 /*!
       
  2360     Calling normalize() on an element converts all its children into a
       
  2361     standard form. This means that adjacent QDomText objects will be
       
  2362     merged into a single text object (QDomCDATASection nodes are not
       
  2363     merged).
       
  2364 */
       
  2365 void QDomNode::normalize()
       
  2366 {
       
  2367     if (!impl)
       
  2368         return;
       
  2369     IMPL->normalize();
       
  2370 }
       
  2371 
       
  2372 /*!
       
  2373     Returns true if the DOM implementation implements the feature \a
       
  2374     feature and this feature is supported by this node in the version
       
  2375     \a version; otherwise returns false.
       
  2376 
       
  2377     \sa QDomImplementation::hasFeature()
       
  2378 */
       
  2379 bool QDomNode::isSupported(const QString& feature, const QString& version) const
       
  2380 {
       
  2381     QDomImplementation i;
       
  2382     return i.hasFeature(feature, version);
       
  2383 }
       
  2384 
       
  2385 /*!
       
  2386     Returns the namespace URI of this node or an empty string if the
       
  2387     node has no namespace URI.
       
  2388 
       
  2389     Only nodes of type \link QDomNode::NodeType ElementNode\endlink or
       
  2390     \link QDomNode::NodeType AttributeNode\endlink can have
       
  2391     namespaces. A namespace URI must be specified at creation time and
       
  2392     cannot be changed later.
       
  2393 
       
  2394     \sa prefix() localName() QDomDocument::createElementNS()
       
  2395     QDomDocument::createAttributeNS()
       
  2396 */
       
  2397 QString QDomNode::namespaceURI() const
       
  2398 {
       
  2399     if (!impl)
       
  2400         return QString();
       
  2401     return IMPL->namespaceURI;
       
  2402 }
       
  2403 
       
  2404 /*!
       
  2405     Returns the namespace prefix of the node or an empty string if the
       
  2406     node has no namespace prefix.
       
  2407 
       
  2408     Only nodes of type \link QDomNode::NodeType ElementNode\endlink or
       
  2409     \link QDomNode::NodeType AttributeNode\endlink can have
       
  2410     namespaces. A namespace prefix must be specified at creation time.
       
  2411     If a node was created with a namespace prefix, you can change it
       
  2412     later with setPrefix().
       
  2413 
       
  2414     If you create an element or attribute with
       
  2415     QDomDocument::createElement() or QDomDocument::createAttribute(),
       
  2416     the prefix will be an empty string. If you use
       
  2417     QDomDocument::createElementNS() or
       
  2418     QDomDocument::createAttributeNS() instead, the prefix will not be
       
  2419     an empty string; but it might be an empty string if the name does
       
  2420     not have a prefix.
       
  2421 
       
  2422     \sa setPrefix() localName() namespaceURI()
       
  2423     QDomDocument::createElementNS() QDomDocument::createAttributeNS()
       
  2424 */
       
  2425 QString QDomNode::prefix() const
       
  2426 {
       
  2427     if (!impl)
       
  2428         return QString();
       
  2429     return IMPL->prefix;
       
  2430 }
       
  2431 
       
  2432 /*!
       
  2433     If the node has a namespace prefix, this function changes the
       
  2434     namespace prefix of the node to \a pre. Otherwise this function
       
  2435     does nothing.
       
  2436 
       
  2437     Only nodes of type \link QDomNode::NodeType ElementNode\endlink or
       
  2438     \link QDomNode::NodeType AttributeNode\endlink can have
       
  2439     namespaces. A namespace prefix must have be specified at creation
       
  2440     time; it is not possible to add a namespace prefix afterwards.
       
  2441 
       
  2442     \sa prefix() localName() namespaceURI()
       
  2443     QDomDocument::createElementNS() QDomDocument::createAttributeNS()
       
  2444 */
       
  2445 void QDomNode::setPrefix(const QString& pre)
       
  2446 {
       
  2447     if (!impl || IMPL->prefix.isNull())
       
  2448         return;
       
  2449     if (isAttr() || isElement())
       
  2450         IMPL->prefix = pre;
       
  2451 }
       
  2452 
       
  2453 /*!
       
  2454     If the node uses namespaces, this function returns the local name
       
  2455     of the node; otherwise it returns an empty string.
       
  2456 
       
  2457     Only nodes of type \link QDomNode::NodeType ElementNode\endlink or
       
  2458     \link QDomNode::NodeType AttributeNode\endlink can have
       
  2459     namespaces. A namespace must have been specified at creation time;
       
  2460     it is not possible to add a namespace afterwards.
       
  2461 
       
  2462     \sa prefix() namespaceURI() QDomDocument::createElementNS()
       
  2463     QDomDocument::createAttributeNS()
       
  2464 */
       
  2465 QString QDomNode::localName() const
       
  2466 {
       
  2467     if (!impl || IMPL->createdWithDom1Interface)
       
  2468         return QString();
       
  2469     return IMPL->name;
       
  2470 }
       
  2471 
       
  2472 /*!
       
  2473     Returns true if the node has attributes; otherwise returns false.
       
  2474 
       
  2475     \sa attributes()
       
  2476 */
       
  2477 bool QDomNode::hasAttributes() const
       
  2478 {
       
  2479     if (!impl || !impl->isElement())
       
  2480         return false;
       
  2481     return static_cast<QDomElementPrivate *>(impl)->hasAttributes();
       
  2482 }
       
  2483 
       
  2484 /*!
       
  2485     Inserts the node \a newChild before the child node \a refChild.
       
  2486     \a refChild must be a direct child of this node. If \a refChild is
       
  2487     \link isNull() null\endlink then \a newChild is inserted as the
       
  2488     node's first child.
       
  2489 
       
  2490     If \a newChild is the child of another node, it is reparented to
       
  2491     this node. If \a newChild is a child of this node, then its
       
  2492     position in the list of children is changed.
       
  2493 
       
  2494     If \a newChild is a QDomDocumentFragment, then the children of the
       
  2495     fragment are removed from the fragment and inserted before \a
       
  2496     refChild.
       
  2497 
       
  2498     Returns a new reference to \a newChild on success or a \link
       
  2499     isNull() null node\endlink on failure.
       
  2500 
       
  2501     The DOM specification disallow inserting attribute nodes, but due
       
  2502     to historical reasons QDom accept them nevertheless.
       
  2503 
       
  2504     \sa insertAfter() replaceChild() removeChild() appendChild()
       
  2505 */
       
  2506 QDomNode QDomNode::insertBefore(const QDomNode& newChild, const QDomNode& refChild)
       
  2507 {
       
  2508     if (!impl)
       
  2509         return QDomNode();
       
  2510     return QDomNode(IMPL->insertBefore(newChild.impl, refChild.impl));
       
  2511 }
       
  2512 
       
  2513 /*!
       
  2514     Inserts the node \a newChild after the child node \a refChild. \a
       
  2515     refChild must be a direct child of this node. If \a refChild is
       
  2516     \link isNull() null\endlink then \a newChild is appended as this
       
  2517     node's last child.
       
  2518 
       
  2519     If \a newChild is the child of another node, it is reparented to
       
  2520     this node. If \a newChild is a child of this node, then its
       
  2521     position in the list of children is changed.
       
  2522 
       
  2523     If \a newChild is a QDomDocumentFragment, then the children of the
       
  2524     fragment are removed from the fragment and inserted after \a
       
  2525     refChild.
       
  2526 
       
  2527     Returns a new reference to \a newChild on success or a \link
       
  2528     isNull() null node\endlink on failure.
       
  2529 
       
  2530     The DOM specification disallow inserting attribute nodes, but due
       
  2531     to historical reasons QDom accept them nevertheless.
       
  2532 
       
  2533     \sa insertBefore() replaceChild() removeChild() appendChild()
       
  2534 */
       
  2535 QDomNode QDomNode::insertAfter(const QDomNode& newChild, const QDomNode& refChild)
       
  2536 {
       
  2537     if (!impl)
       
  2538         return QDomNode();
       
  2539     return QDomNode(IMPL->insertAfter(newChild.impl, refChild.impl));
       
  2540 }
       
  2541 
       
  2542 /*!
       
  2543     Replaces \a oldChild with \a newChild. \a oldChild must be a
       
  2544     direct child of this node.
       
  2545 
       
  2546     If \a newChild is the child of another node, it is reparented to
       
  2547     this node. If \a newChild is a child of this node, then its
       
  2548     position in the list of children is changed.
       
  2549 
       
  2550     If \a newChild is a QDomDocumentFragment, then \a oldChild is
       
  2551     replaced by all of the children of the fragment.
       
  2552 
       
  2553     Returns a new reference to \a oldChild on success or a \link
       
  2554     isNull() null node\endlink an failure.
       
  2555 
       
  2556     \sa insertBefore() insertAfter() removeChild() appendChild()
       
  2557 */
       
  2558 QDomNode QDomNode::replaceChild(const QDomNode& newChild, const QDomNode& oldChild)
       
  2559 {
       
  2560     if (!impl || !newChild.impl || !oldChild.impl)
       
  2561         return QDomNode();
       
  2562     return QDomNode(IMPL->replaceChild(newChild.impl, oldChild.impl));
       
  2563 }
       
  2564 
       
  2565 /*!
       
  2566     Removes \a oldChild from the list of children. \a oldChild must be
       
  2567     a direct child of this node.
       
  2568 
       
  2569     Returns a new reference to \a oldChild on success or a \link
       
  2570     isNull() null node\endlink on failure.
       
  2571 
       
  2572     \sa insertBefore() insertAfter() replaceChild() appendChild()
       
  2573 */
       
  2574 QDomNode QDomNode::removeChild(const QDomNode& oldChild)
       
  2575 {
       
  2576     if (!impl)
       
  2577         return QDomNode();
       
  2578 
       
  2579     if (oldChild.isNull())
       
  2580         return QDomNode();
       
  2581 
       
  2582     return QDomNode(IMPL->removeChild(oldChild.impl));
       
  2583 }
       
  2584 
       
  2585 /*!
       
  2586     Appends \a newChild as the node's last child.
       
  2587 
       
  2588     If \a newChild is the child of another node, it is reparented to
       
  2589     this node. If \a newChild is a child of this node, then its
       
  2590     position in the list of children is changed.
       
  2591 
       
  2592     If \a newChild is a QDomDocumentFragment, then the children of the
       
  2593     fragment are removed from the fragment and appended.
       
  2594 
       
  2595     If \a newChild is a QDomElement and this node is a QDomDocument that
       
  2596     already has an element node as a child, \a newChild is not added as
       
  2597     a child and a null node is returned.
       
  2598 
       
  2599     Returns a new reference to \a newChild on success or a \link
       
  2600     isNull() null node\endlink on failure.
       
  2601 
       
  2602     Calling this function on a null node(created, for example, with
       
  2603     the default constructor) does nothing and returns a \link isNull()
       
  2604     null node\endlink.
       
  2605 
       
  2606     The DOM specification disallow inserting attribute nodes, but for
       
  2607     historical reasons, QDom accepts them anyway.
       
  2608 
       
  2609     \sa insertBefore() insertAfter() replaceChild() removeChild()
       
  2610 */
       
  2611 QDomNode QDomNode::appendChild(const QDomNode& newChild)
       
  2612 {
       
  2613     if (!impl) {
       
  2614         qWarning("Calling appendChild() on a null node does nothing.");
       
  2615         return QDomNode();
       
  2616     }
       
  2617     return QDomNode(IMPL->appendChild(newChild.impl));
       
  2618 }
       
  2619 
       
  2620 /*!
       
  2621     Returns true if the node has one or more children; otherwise
       
  2622     returns false.
       
  2623 */
       
  2624 bool QDomNode::hasChildNodes() const
       
  2625 {
       
  2626     if (!impl)
       
  2627         return false;
       
  2628     return IMPL->first != 0;
       
  2629 }
       
  2630 
       
  2631 /*!
       
  2632     Returns true if this node is null (i.e. if it has no type or
       
  2633     contents); otherwise returns false.
       
  2634 */
       
  2635 bool QDomNode::isNull() const
       
  2636 {
       
  2637     return (impl == 0);
       
  2638 }
       
  2639 
       
  2640 /*!
       
  2641     Converts the node into a null node; if it was not a null node
       
  2642     before, its type and contents are deleted.
       
  2643 
       
  2644     \sa isNull()
       
  2645 */
       
  2646 void QDomNode::clear()
       
  2647 {
       
  2648     if (impl && !impl->ref.deref())
       
  2649         delete impl;
       
  2650     impl = 0;
       
  2651 }
       
  2652 
       
  2653 /*!
       
  2654     Returns the first direct child node for which nodeName() equals \a
       
  2655     name.
       
  2656 
       
  2657     If no such direct child exists, a \link isNull() null node\endlink
       
  2658     is returned.
       
  2659 
       
  2660     \sa nodeName()
       
  2661 */
       
  2662 QDomNode QDomNode::namedItem(const QString& name) const
       
  2663 {
       
  2664     if (!impl)
       
  2665         return QDomNode();
       
  2666     return QDomNode(impl->namedItem(name));
       
  2667 }
       
  2668 
       
  2669 /*!
       
  2670     Writes the XML representation of the node and all its children to
       
  2671     the stream \a str. This function uses \a indent as the amount of
       
  2672     space to indent the node.
       
  2673 
       
  2674     If this node is a document node, the encoding of text stream \a str's encoding is
       
  2675     set by treating a processing instruction by name "xml" as an XML declaration, if such a one exists,
       
  2676     and otherwise defaults to UTF-8. XML declarations are not processing instructions, but this
       
  2677     behavior exists for historical reasons. If this node is not a document node,
       
  2678     the text stream's encoding is used.
       
  2679 
       
  2680     If the document contains invalid XML characters or characters that cannot be
       
  2681     encoded in the given encoding, the result and behavior is undefined.
       
  2682 
       
  2683 */
       
  2684 void QDomNode::save(QTextStream& str, int indent) const
       
  2685 {
       
  2686     save(str, indent, QDomNode::EncodingFromDocument);
       
  2687 }
       
  2688 
       
  2689 /*!
       
  2690     If \a encodingPolicy is QDomNode::EncodingFromDocument, this function behaves as save(QTextStream &str, int indent).
       
  2691 
       
  2692     If \a encodingPolicy is EncodingFromTextStream and this node is a document node, this
       
  2693     function behaves as save(QTextStream &str, int indent) with the exception that the encoding
       
  2694     specified in the text stream \a str is used.
       
  2695 
       
  2696     If the document contains invalid XML characters or characters that cannot be
       
  2697     encoded in the given encoding, the result and behavior is undefined.
       
  2698 
       
  2699     \since 4.2
       
  2700  */
       
  2701 void QDomNode::save(QTextStream& str, int indent, EncodingPolicy encodingPolicy) const
       
  2702 {
       
  2703     if (!impl)
       
  2704         return;
       
  2705 
       
  2706     if(isDocument())
       
  2707         static_cast<const QDomDocumentPrivate *>(impl)->saveDocument(str, indent, encodingPolicy);
       
  2708     else
       
  2709         IMPL->save(str, 1, indent);
       
  2710 }
       
  2711 
       
  2712 /*!
       
  2713     \relates QDomNode
       
  2714 
       
  2715     Writes the XML representation of the node \a node and all its
       
  2716     children to the stream \a str.
       
  2717 */
       
  2718 QTextStream& operator<<(QTextStream& str, const QDomNode& node)
       
  2719 {
       
  2720     node.save(str, 1);
       
  2721 
       
  2722     return str;
       
  2723 }
       
  2724 
       
  2725 /*!
       
  2726     Returns true if the node is an attribute; otherwise returns false.
       
  2727 
       
  2728     If this function returns true, it does not imply that this object
       
  2729     is a QDomAttribute; you can get the QDomAttribute with
       
  2730     toAttribute().
       
  2731 
       
  2732     \sa toAttr()
       
  2733 */
       
  2734 bool QDomNode::isAttr() const
       
  2735 {
       
  2736     if(impl)
       
  2737         return impl->isAttr();
       
  2738     return false;
       
  2739 }
       
  2740 
       
  2741 /*!
       
  2742     Returns true if the node is a CDATA section; otherwise returns
       
  2743     false.
       
  2744 
       
  2745     If this function returns true, it does not imply that this object
       
  2746     is a QDomCDATASection; you can get the QDomCDATASection with
       
  2747     toCDATASection().
       
  2748 
       
  2749     \sa toCDATASection()
       
  2750 */
       
  2751 bool QDomNode::isCDATASection() const
       
  2752 {
       
  2753     if(impl)
       
  2754         return impl->isCDATASection();
       
  2755     return false;
       
  2756 }
       
  2757 
       
  2758 /*!
       
  2759     Returns true if the node is a document fragment; otherwise returns
       
  2760     false.
       
  2761 
       
  2762     If this function returns true, it does not imply that this object
       
  2763     is a QDomDocumentFragment; you can get the QDomDocumentFragment
       
  2764     with toDocumentFragment().
       
  2765 
       
  2766     \sa toDocumentFragment()
       
  2767 */
       
  2768 bool QDomNode::isDocumentFragment() const
       
  2769 {
       
  2770     if(impl)
       
  2771         return impl->isDocumentFragment();
       
  2772     return false;
       
  2773 }
       
  2774 
       
  2775 /*!
       
  2776     Returns true if the node is a document; otherwise returns false.
       
  2777 
       
  2778     If this function returns true, it does not imply that this object
       
  2779     is a QDomDocument; you can get the QDomDocument with toDocument().
       
  2780 
       
  2781     \sa toDocument()
       
  2782 */
       
  2783 bool QDomNode::isDocument() const
       
  2784 {
       
  2785     if(impl)
       
  2786         return impl->isDocument();
       
  2787     return false;
       
  2788 }
       
  2789 
       
  2790 /*!
       
  2791     Returns true if the node is a document type; otherwise returns
       
  2792     false.
       
  2793 
       
  2794     If this function returns true, it does not imply that this object
       
  2795     is a QDomDocumentType; you can get the QDomDocumentType with
       
  2796     toDocumentType().
       
  2797 
       
  2798     \sa toDocumentType()
       
  2799 */
       
  2800 bool QDomNode::isDocumentType() const
       
  2801 {
       
  2802     if(impl)
       
  2803         return impl->isDocumentType();
       
  2804     return false;
       
  2805 }
       
  2806 
       
  2807 /*!
       
  2808     Returns true if the node is an element; otherwise returns false.
       
  2809 
       
  2810     If this function returns true, it does not imply that this object
       
  2811     is a QDomElement; you can get the QDomElement with toElement().
       
  2812 
       
  2813     \sa toElement()
       
  2814 */
       
  2815 bool QDomNode::isElement() const
       
  2816 {
       
  2817     if(impl)
       
  2818         return impl->isElement();
       
  2819     return false;
       
  2820 }
       
  2821 
       
  2822 /*!
       
  2823     Returns true if the node is an entity reference; otherwise returns
       
  2824     false.
       
  2825 
       
  2826     If this function returns true, it does not imply that this object
       
  2827     is a QDomEntityReference; you can get the QDomEntityReference with
       
  2828     toEntityReference().
       
  2829 
       
  2830     \sa toEntityReference()
       
  2831 */
       
  2832 bool QDomNode::isEntityReference() const
       
  2833 {
       
  2834     if(impl)
       
  2835         return impl->isEntityReference();
       
  2836     return false;
       
  2837 }
       
  2838 
       
  2839 /*!
       
  2840     Returns true if the node is a text node; otherwise returns false.
       
  2841 
       
  2842     If this function returns true, it does not imply that this object
       
  2843     is a QDomText; you can get the QDomText with toText().
       
  2844 
       
  2845     \sa toText()
       
  2846 */
       
  2847 bool QDomNode::isText() const
       
  2848 {
       
  2849     if(impl)
       
  2850         return impl->isText();
       
  2851     return false;
       
  2852 }
       
  2853 
       
  2854 /*!
       
  2855     Returns true if the node is an entity; otherwise returns false.
       
  2856 
       
  2857     If this function returns true, it does not imply that this object
       
  2858     is a QDomEntity; you can get the QDomEntity with toEntity().
       
  2859 
       
  2860     \sa toEntity()
       
  2861 */
       
  2862 bool QDomNode::isEntity() const
       
  2863 {
       
  2864     if(impl)
       
  2865         return impl->isEntity();
       
  2866     return false;
       
  2867 }
       
  2868 
       
  2869 /*!
       
  2870     Returns true if the node is a notation; otherwise returns false.
       
  2871 
       
  2872     If this function returns true, it does not imply that this object
       
  2873     is a QDomNotation; you can get the QDomNotation with toNotation().
       
  2874 
       
  2875     \sa toNotation()
       
  2876 */
       
  2877 bool QDomNode::isNotation() const
       
  2878 {
       
  2879     if(impl)
       
  2880         return impl->isNotation();
       
  2881     return false;
       
  2882 }
       
  2883 
       
  2884 /*!
       
  2885     Returns true if the node is a processing instruction; otherwise
       
  2886     returns false.
       
  2887 
       
  2888     If this function returns true, it does not imply that this object
       
  2889     is a QDomProcessingInstruction; you can get the
       
  2890     QProcessingInstruction with toProcessingInstruction().
       
  2891 
       
  2892     \sa toProcessingInstruction()
       
  2893 */
       
  2894 bool QDomNode::isProcessingInstruction() const
       
  2895 {
       
  2896     if(impl)
       
  2897         return impl->isProcessingInstruction();
       
  2898     return false;
       
  2899 }
       
  2900 
       
  2901 /*!
       
  2902     Returns true if the node is a character data node; otherwise
       
  2903     returns false.
       
  2904 
       
  2905     If this function returns true, it does not imply that this object
       
  2906     is a QDomCharacterData; you can get the QDomCharacterData with
       
  2907     toCharacterData().
       
  2908 
       
  2909     \sa toCharacterData()
       
  2910 */
       
  2911 bool QDomNode::isCharacterData() const
       
  2912 {
       
  2913     if (impl)
       
  2914         return impl->isCharacterData();
       
  2915     return false;
       
  2916 }
       
  2917 
       
  2918 /*!
       
  2919     Returns true if the node is a comment; otherwise returns false.
       
  2920 
       
  2921     If this function returns true, it does not imply that this object
       
  2922     is a QDomComment; you can get the QDomComment with toComment().
       
  2923 
       
  2924     \sa toComment()
       
  2925 */
       
  2926 bool QDomNode::isComment() const
       
  2927 {
       
  2928     if (impl)
       
  2929         return impl->isComment();
       
  2930     return false;
       
  2931 }
       
  2932 
       
  2933 #undef IMPL
       
  2934 
       
  2935 /*!
       
  2936     Returns the first child element with tag name \a tagName if tagName is non-empty;
       
  2937     otherwise returns the first child element.  Returns a null element if no
       
  2938     such child exists.
       
  2939 
       
  2940     \sa lastChildElement() previousSiblingElement() nextSiblingElement()
       
  2941 */
       
  2942 
       
  2943 QDomElement QDomNode::firstChildElement(const QString &tagName) const
       
  2944 {
       
  2945     for (QDomNode child = firstChild(); !child.isNull(); child = child.nextSibling()) {
       
  2946         if (child.isElement()) {
       
  2947             QDomElement elt = child.toElement();
       
  2948             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  2949                 return elt;
       
  2950         }
       
  2951     }
       
  2952     return QDomElement();
       
  2953 }
       
  2954 
       
  2955 /*!
       
  2956     Returns the last child element with tag name \a tagName if tagName is non-empty;
       
  2957     otherwise returns the first child element. Returns a null element if no
       
  2958     such child exists.
       
  2959 
       
  2960     \sa firstChildElement() previousSiblingElement() nextSiblingElement()
       
  2961 */
       
  2962 
       
  2963 QDomElement QDomNode::lastChildElement(const QString &tagName) const
       
  2964 {
       
  2965     for (QDomNode child = lastChild(); !child.isNull(); child = child.previousSibling()) {
       
  2966         if (child.isElement()) {
       
  2967             QDomElement elt = child.toElement();
       
  2968             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  2969                 return elt;
       
  2970         }
       
  2971     }
       
  2972     return QDomElement();
       
  2973 }
       
  2974 
       
  2975 /*!
       
  2976     Returns the next sibling element with tag name \a tagName if \a tagName
       
  2977     is non-empty; otherwise returns any next sibling element.
       
  2978     Returns a null element if no such sibling exists.
       
  2979 
       
  2980     \sa firstChildElement() previousSiblingElement() lastChildElement()
       
  2981 */
       
  2982 
       
  2983 QDomElement QDomNode::nextSiblingElement(const QString &tagName) const
       
  2984 {
       
  2985     for (QDomNode sib = nextSibling(); !sib.isNull(); sib = sib.nextSibling()) {
       
  2986         if (sib.isElement()) {
       
  2987             QDomElement elt = sib.toElement();
       
  2988             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  2989                 return elt;
       
  2990         }
       
  2991     }
       
  2992     return QDomElement();
       
  2993 }
       
  2994 
       
  2995 /*!
       
  2996     Returns the previous sibilng element with tag name \a tagName if \a tagName
       
  2997     is non-empty; otherwise returns any previous sibling element.
       
  2998     Returns a null element if no such sibling exists.
       
  2999 
       
  3000     \sa firstChildElement(), nextSiblingElement(), lastChildElement()
       
  3001 */
       
  3002 
       
  3003 QDomElement QDomNode::previousSiblingElement(const QString &tagName) const
       
  3004 {
       
  3005     for (QDomNode sib = previousSibling(); !sib.isNull(); sib = sib.previousSibling()) {
       
  3006         if (sib.isElement()) {
       
  3007             QDomElement elt = sib.toElement();
       
  3008             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  3009                 return elt;
       
  3010         }
       
  3011     }
       
  3012     return QDomElement();
       
  3013 }
       
  3014 
       
  3015 /*!
       
  3016     \since 4.1
       
  3017 
       
  3018     For nodes created by QDomDocument::setContent(), this function
       
  3019     returns the line number in the XML document where the node was parsed.
       
  3020     Otherwise, -1 is returned.
       
  3021 
       
  3022     \sa columnNumber(), QDomDocument::setContent()
       
  3023 */
       
  3024 int QDomNode::lineNumber() const
       
  3025 {
       
  3026     return impl ? impl->lineNumber : -1;
       
  3027 }
       
  3028 
       
  3029 /*!
       
  3030     \since 4.1
       
  3031 
       
  3032     For nodes created by QDomDocument::setContent(), this function
       
  3033     returns the column number in the XML document where the node was parsed.
       
  3034     Otherwise, -1 is returned.
       
  3035 
       
  3036     \sa lineNumber(), QDomDocument::setContent()
       
  3037 */
       
  3038 int QDomNode::columnNumber() const
       
  3039 {
       
  3040     return impl ? impl->columnNumber : -1;
       
  3041 }
       
  3042 
       
  3043 
       
  3044 /**************************************************************
       
  3045  *
       
  3046  * QDomNamedNodeMapPrivate
       
  3047  *
       
  3048  **************************************************************/
       
  3049 
       
  3050 QDomNamedNodeMapPrivate::QDomNamedNodeMapPrivate(QDomNodePrivate* n)
       
  3051 {
       
  3052     ref = 1;
       
  3053     readonly = false;
       
  3054     parent = n;
       
  3055     appendToParent = false;
       
  3056 }
       
  3057 
       
  3058 QDomNamedNodeMapPrivate::~QDomNamedNodeMapPrivate()
       
  3059 {
       
  3060     clearMap();
       
  3061 }
       
  3062 
       
  3063 QDomNamedNodeMapPrivate* QDomNamedNodeMapPrivate::clone(QDomNodePrivate* p)
       
  3064 {
       
  3065     QScopedPointer<QDomNamedNodeMapPrivate> m(new QDomNamedNodeMapPrivate(p));
       
  3066     m->readonly = readonly;
       
  3067     m->appendToParent = appendToParent;
       
  3068 
       
  3069     QHash<QString, QDomNodePrivate*>::const_iterator it = map.constBegin();
       
  3070     for (; it != map.constEnd(); ++it) {
       
  3071         QDomNodePrivate *new_node = (*it)->cloneNode();
       
  3072         new_node->setParent(p);
       
  3073         m->setNamedItem(new_node);
       
  3074     }
       
  3075 
       
  3076     // we are no longer interested in ownership
       
  3077     m->ref.deref();
       
  3078     return m.take();
       
  3079 }
       
  3080 
       
  3081 void QDomNamedNodeMapPrivate::clearMap()
       
  3082 {
       
  3083     // Dereference all of our children if we took references
       
  3084     if (!appendToParent) {
       
  3085         QHash<QString, QDomNodePrivate *>::const_iterator it = map.constBegin();
       
  3086         for (; it != map.constEnd(); ++it)
       
  3087             if (!(*it)->ref.deref())
       
  3088                 delete *it;
       
  3089     }
       
  3090     map.clear();
       
  3091 }
       
  3092 
       
  3093 QDomNodePrivate* QDomNamedNodeMapPrivate::namedItem(const QString& name) const
       
  3094 {
       
  3095     QDomNodePrivate* p = map[name];
       
  3096     return p;
       
  3097 }
       
  3098 
       
  3099 QDomNodePrivate* QDomNamedNodeMapPrivate::namedItemNS(const QString& nsURI, const QString& localName) const
       
  3100 {
       
  3101     QHash<QString, QDomNodePrivate *>::const_iterator it = map.constBegin();
       
  3102     QDomNodePrivate *n;
       
  3103     for (; it != map.constEnd(); ++it) {
       
  3104         n = *it;
       
  3105         if (!n->prefix.isNull()) {
       
  3106             // node has a namespace
       
  3107             if (n->namespaceURI == nsURI && n->name == localName)
       
  3108                 return n;
       
  3109         }
       
  3110     }
       
  3111     return 0;
       
  3112 }
       
  3113 
       
  3114 QDomNodePrivate* QDomNamedNodeMapPrivate::setNamedItem(QDomNodePrivate* arg)
       
  3115 {
       
  3116     if (readonly || !arg)
       
  3117         return 0;
       
  3118 
       
  3119     if (appendToParent)
       
  3120         return parent->appendChild(arg);
       
  3121 
       
  3122     QDomNodePrivate *n = map.value(arg->nodeName());
       
  3123     // We take a reference
       
  3124     arg->ref.ref();
       
  3125     map.insertMulti(arg->nodeName(), arg);
       
  3126     return n;
       
  3127 }
       
  3128 
       
  3129 QDomNodePrivate* QDomNamedNodeMapPrivate::setNamedItemNS(QDomNodePrivate* arg)
       
  3130 {
       
  3131     if (readonly || !arg)
       
  3132         return 0;
       
  3133 
       
  3134     if (appendToParent)
       
  3135         return parent->appendChild(arg);
       
  3136 
       
  3137     if (!arg->prefix.isNull()) {
       
  3138         // node has a namespace
       
  3139         QDomNodePrivate *n = namedItemNS(arg->namespaceURI, arg->name);
       
  3140         // We take a reference
       
  3141         arg->ref.ref();
       
  3142         map.insertMulti(arg->nodeName(), arg);
       
  3143         return n;
       
  3144     } else {
       
  3145         // ### check the following code if it is ok
       
  3146         return setNamedItem(arg);
       
  3147     }
       
  3148 }
       
  3149 
       
  3150 QDomNodePrivate* QDomNamedNodeMapPrivate::removeNamedItem(const QString& name)
       
  3151 {
       
  3152     if (readonly)
       
  3153         return 0;
       
  3154 
       
  3155     QDomNodePrivate* p = namedItem(name);
       
  3156     if (p == 0)
       
  3157         return 0;
       
  3158     if (appendToParent)
       
  3159         return parent->removeChild(p);
       
  3160 
       
  3161     map.remove(p->nodeName());
       
  3162     // We took a reference, so we have to free one here
       
  3163     p->ref.deref();
       
  3164     return p;
       
  3165 }
       
  3166 
       
  3167 QDomNodePrivate* QDomNamedNodeMapPrivate::item(int index) const
       
  3168 {
       
  3169     if ((uint)index >= length())
       
  3170         return 0;
       
  3171     return *(map.constBegin() + index);
       
  3172 }
       
  3173 
       
  3174 // ### Qt 5: convert all length/size() functions in QDom to use int instead of uint.
       
  3175 uint QDomNamedNodeMapPrivate::length() const
       
  3176 {
       
  3177     return map.count();
       
  3178 }
       
  3179 
       
  3180 bool QDomNamedNodeMapPrivate::contains(const QString& name) const
       
  3181 {
       
  3182     return map.value(name) != 0;
       
  3183 }
       
  3184 
       
  3185 bool QDomNamedNodeMapPrivate::containsNS(const QString& nsURI, const QString & localName) const
       
  3186 {
       
  3187     return namedItemNS(nsURI, localName) != 0;
       
  3188 }
       
  3189 
       
  3190 /**************************************************************
       
  3191  *
       
  3192  * QDomNamedNodeMap
       
  3193  *
       
  3194  **************************************************************/
       
  3195 
       
  3196 #define IMPL ((QDomNamedNodeMapPrivate*)impl)
       
  3197 
       
  3198 /*!
       
  3199     \class QDomNamedNodeMap
       
  3200     \reentrant
       
  3201     \brief The QDomNamedNodeMap class contains a collection of nodes
       
  3202     that can be accessed by name.
       
  3203 
       
  3204     \inmodule QtXml
       
  3205     \ingroup xml-tools
       
  3206 
       
  3207     Note that QDomNamedNodeMap does not inherit from QDomNodeList.
       
  3208     QDomNamedNodeMaps do not provide any specific node ordering.
       
  3209     Although nodes in a QDomNamedNodeMap may be accessed by an ordinal
       
  3210     index, this is simply to allow a convenient enumeration of the
       
  3211     contents of a QDomNamedNodeMap, and does not imply that the DOM
       
  3212     specifies an ordering of the nodes.
       
  3213 
       
  3214     The QDomNamedNodeMap is used in three places:
       
  3215     \list 1
       
  3216     \i QDomDocumentType::entities() returns a map of all entities
       
  3217         described in the DTD.
       
  3218     \i QDomDocumentType::notations() returns a map of all notations
       
  3219         described in the DTD.
       
  3220     \i QDomNode::attributes() returns a map of all attributes of an
       
  3221         element.
       
  3222     \endlist
       
  3223 
       
  3224     Items in the map are identified by the name which QDomNode::name()
       
  3225     returns. Nodes are retrieved using namedItem(), namedItemNS() or
       
  3226     item(). New nodes are inserted with setNamedItem() or
       
  3227     setNamedItemNS() and removed with removeNamedItem() or
       
  3228     removeNamedItemNS(). Use contains() to see if an item with the
       
  3229     given name is in the named node map. The number of items is
       
  3230     returned by length().
       
  3231 
       
  3232     Terminology: in this class we use "item" and "node"
       
  3233     interchangeably.
       
  3234 */
       
  3235 
       
  3236 /*!
       
  3237     Constructs an empty named node map.
       
  3238 */
       
  3239 QDomNamedNodeMap::QDomNamedNodeMap()
       
  3240 {
       
  3241     impl = 0;
       
  3242 }
       
  3243 
       
  3244 /*!
       
  3245     Constructs a copy of \a n.
       
  3246 */
       
  3247 QDomNamedNodeMap::QDomNamedNodeMap(const QDomNamedNodeMap &n)
       
  3248 {
       
  3249     impl = n.impl;
       
  3250     if (impl)
       
  3251         impl->ref.ref();
       
  3252 }
       
  3253 
       
  3254 QDomNamedNodeMap::QDomNamedNodeMap(QDomNamedNodeMapPrivate *n)
       
  3255 {
       
  3256     impl = n;
       
  3257     if (impl)
       
  3258         impl->ref.ref();
       
  3259 }
       
  3260 
       
  3261 /*!
       
  3262     Assigns \a n to this named node map.
       
  3263 */
       
  3264 QDomNamedNodeMap& QDomNamedNodeMap::operator=(const QDomNamedNodeMap &n)
       
  3265 {
       
  3266     if (n.impl)
       
  3267         n.impl->ref.ref();
       
  3268     if (impl && !impl->ref.deref())
       
  3269         delete impl;
       
  3270     impl = n.impl;
       
  3271     return *this;
       
  3272 }
       
  3273 
       
  3274 /*!
       
  3275     Returns true if \a n and this named node map are equal; otherwise
       
  3276     returns false.
       
  3277 */
       
  3278 bool QDomNamedNodeMap::operator== (const QDomNamedNodeMap& n) const
       
  3279 {
       
  3280     return (impl == n.impl);
       
  3281 }
       
  3282 
       
  3283 /*!
       
  3284     Returns true if \a n and this named node map are not equal;
       
  3285     otherwise returns false.
       
  3286 */
       
  3287 bool QDomNamedNodeMap::operator!= (const QDomNamedNodeMap& n) const
       
  3288 {
       
  3289     return (impl != n.impl);
       
  3290 }
       
  3291 
       
  3292 /*!
       
  3293     Destroys the object and frees its resources.
       
  3294 */
       
  3295 QDomNamedNodeMap::~QDomNamedNodeMap()
       
  3296 {
       
  3297     if (impl && !impl->ref.deref())
       
  3298         delete impl;
       
  3299 }
       
  3300 
       
  3301 /*!
       
  3302     Returns the node called \a name.
       
  3303 
       
  3304     If the named node map does not contain such a node, a \link
       
  3305     QDomNode::isNull() null node\endlink is returned. A node's name is
       
  3306     the name returned by QDomNode::nodeName().
       
  3307 
       
  3308     \sa setNamedItem() namedItemNS()
       
  3309 */
       
  3310 QDomNode QDomNamedNodeMap::namedItem(const QString& name) const
       
  3311 {
       
  3312     if (!impl)
       
  3313         return QDomNode();
       
  3314     return QDomNode(IMPL->namedItem(name));
       
  3315 }
       
  3316 
       
  3317 /*!
       
  3318     Inserts the node \a newNode into the named node map. The name used
       
  3319     by the map is the node name of \a newNode as returned by
       
  3320     QDomNode::nodeName().
       
  3321 
       
  3322     If the new node replaces an existing node, i.e. the map contains a
       
  3323     node with the same name, the replaced node is returned.
       
  3324 
       
  3325     \sa namedItem() removeNamedItem() setNamedItemNS()
       
  3326 */
       
  3327 QDomNode QDomNamedNodeMap::setNamedItem(const QDomNode& newNode)
       
  3328 {
       
  3329     if (!impl)
       
  3330         return QDomNode();
       
  3331     return QDomNode(IMPL->setNamedItem((QDomNodePrivate*)newNode.impl));
       
  3332 }
       
  3333 
       
  3334 /*!
       
  3335     Removes the node called \a name from the map.
       
  3336 
       
  3337     The function returns the removed node or a \link
       
  3338     QDomNode::isNull() null node\endlink if the map did not contain a
       
  3339     node called \a name.
       
  3340 
       
  3341     \sa setNamedItem() namedItem() removeNamedItemNS()
       
  3342 */
       
  3343 QDomNode QDomNamedNodeMap::removeNamedItem(const QString& name)
       
  3344 {
       
  3345     if (!impl)
       
  3346         return QDomNode();
       
  3347     return QDomNode(IMPL->removeNamedItem(name));
       
  3348 }
       
  3349 
       
  3350 /*!
       
  3351     Retrieves the node at position \a index.
       
  3352 
       
  3353     This can be used to iterate over the map. Note that the nodes in
       
  3354     the map are ordered arbitrarily.
       
  3355 
       
  3356     \sa length()
       
  3357 */
       
  3358 QDomNode QDomNamedNodeMap::item(int index) const
       
  3359 {
       
  3360     if (!impl)
       
  3361         return QDomNode();
       
  3362     return QDomNode(IMPL->item(index));
       
  3363 }
       
  3364 
       
  3365 /*!
       
  3366     Returns the node associated with the local name \a localName and
       
  3367     the namespace URI \a nsURI.
       
  3368 
       
  3369     If the map does not contain such a node, a \link
       
  3370     QDomNode::isNull() null node\endlink is returned.
       
  3371 
       
  3372     \sa setNamedItemNS() namedItem()
       
  3373 */
       
  3374 QDomNode QDomNamedNodeMap::namedItemNS(const QString& nsURI, const QString& localName) const
       
  3375 {
       
  3376     if (!impl)
       
  3377         return QDomNode();
       
  3378     return QDomNode(IMPL->namedItemNS(nsURI, localName));
       
  3379 }
       
  3380 
       
  3381 /*!
       
  3382     Inserts the node \a newNode in the map. If a node with the same
       
  3383     namespace URI and the same local name already exists in the map,
       
  3384     it is replaced by \a newNode. If the new node replaces an existing
       
  3385     node, the replaced node is returned.
       
  3386 
       
  3387     \sa namedItemNS() removeNamedItemNS() setNamedItem()
       
  3388 */
       
  3389 QDomNode QDomNamedNodeMap::setNamedItemNS(const QDomNode& newNode)
       
  3390 {
       
  3391     if (!impl)
       
  3392         return QDomNode();
       
  3393     return QDomNode(IMPL->setNamedItemNS((QDomNodePrivate*)newNode.impl));
       
  3394 }
       
  3395 
       
  3396 /*!
       
  3397     Removes the node with the local name \a localName and the
       
  3398     namespace URI \a nsURI from the map.
       
  3399 
       
  3400     The function returns the removed node or a \link
       
  3401     QDomNode::isNull() null node\endlink if the map did not contain a
       
  3402     node with the local name \a localName and the namespace URI \a
       
  3403     nsURI.
       
  3404 
       
  3405     \sa setNamedItemNS() namedItemNS() removeNamedItem()
       
  3406 */
       
  3407 QDomNode QDomNamedNodeMap::removeNamedItemNS(const QString& nsURI, const QString& localName)
       
  3408 {
       
  3409     if (!impl)
       
  3410         return QDomNode();
       
  3411     QDomNodePrivate *n = IMPL->namedItemNS(nsURI, localName);
       
  3412     if (!n)
       
  3413         return QDomNode();
       
  3414     return QDomNode(IMPL->removeNamedItem(n->name));
       
  3415 }
       
  3416 
       
  3417 /*!
       
  3418     Returns the number of nodes in the map.
       
  3419 
       
  3420     \sa item()
       
  3421 */
       
  3422 uint QDomNamedNodeMap::length() const
       
  3423 {
       
  3424     if (!impl)
       
  3425         return 0;
       
  3426     return IMPL->length();
       
  3427 }
       
  3428 
       
  3429 /*!
       
  3430     \fn bool QDomNamedNodeMap::isEmpty() const
       
  3431 
       
  3432     Returns true if the map is empty; otherwise returns false. This function is
       
  3433     provided for Qt API consistency.
       
  3434 */
       
  3435 
       
  3436 /*!
       
  3437     \fn int QDomNamedNodeMap::count() const
       
  3438 
       
  3439     This function is provided for Qt API consistency. It is equivalent to length().
       
  3440 */
       
  3441 
       
  3442 /*!
       
  3443     \fn int QDomNamedNodeMap::size() const
       
  3444 
       
  3445     This function is provided for Qt API consistency. It is equivalent to length().
       
  3446 */
       
  3447 
       
  3448 /*!
       
  3449     Returns true if the map contains a node called \a name; otherwise
       
  3450     returns false.
       
  3451 
       
  3452     \bold{Note:} This function does not take the presence of namespaces into account.
       
  3453     Use namedItemNS() to test whether the map contains a node with a specific namespace
       
  3454     URI and name.
       
  3455 */
       
  3456 bool QDomNamedNodeMap::contains(const QString& name) const
       
  3457 {
       
  3458     if (!impl)
       
  3459         return false;
       
  3460     return IMPL->contains(name);
       
  3461 }
       
  3462 
       
  3463 #undef IMPL
       
  3464 
       
  3465 /**************************************************************
       
  3466  *
       
  3467  * QDomDocumentTypePrivate
       
  3468  *
       
  3469  **************************************************************/
       
  3470 
       
  3471 QDomDocumentTypePrivate::QDomDocumentTypePrivate(QDomDocumentPrivate* doc, QDomNodePrivate* parent)
       
  3472     : QDomNodePrivate(doc, parent)
       
  3473 {
       
  3474     init();
       
  3475 }
       
  3476 
       
  3477 QDomDocumentTypePrivate::QDomDocumentTypePrivate(QDomDocumentTypePrivate* n, bool deep)
       
  3478     : QDomNodePrivate(n, deep)
       
  3479 {
       
  3480     init();
       
  3481     // Refill the maps with our new children
       
  3482     QDomNodePrivate* p = first;
       
  3483     while (p) {
       
  3484         if (p->isEntity())
       
  3485             // Dont use normal insert function since we would create infinite recursion
       
  3486             entities->map.insertMulti(p->nodeName(), p);
       
  3487         if (p->isNotation())
       
  3488             // Dont use normal insert function since we would create infinite recursion
       
  3489             notations->map.insertMulti(p->nodeName(), p);
       
  3490         p = p->next;
       
  3491     }
       
  3492 }
       
  3493 
       
  3494 QDomDocumentTypePrivate::~QDomDocumentTypePrivate()
       
  3495 {
       
  3496     if (!entities->ref.deref())
       
  3497         delete entities;
       
  3498     if (!notations->ref.deref())
       
  3499         delete notations;
       
  3500 }
       
  3501 
       
  3502 void QDomDocumentTypePrivate::init()
       
  3503 {
       
  3504     entities = new QDomNamedNodeMapPrivate(this);
       
  3505     QT_TRY {
       
  3506         notations = new QDomNamedNodeMapPrivate(this);
       
  3507         publicId.clear();
       
  3508         systemId.clear();
       
  3509         internalSubset.clear();
       
  3510 
       
  3511         entities->setAppendToParent(true);
       
  3512         notations->setAppendToParent(true);
       
  3513     } QT_CATCH(...) {
       
  3514         delete entities;
       
  3515         QT_RETHROW;
       
  3516     }
       
  3517 }
       
  3518 
       
  3519 QDomNodePrivate* QDomDocumentTypePrivate::cloneNode(bool deep)
       
  3520 {
       
  3521     QDomNodePrivate* p = new QDomDocumentTypePrivate(this, deep);
       
  3522     // We are not interested in this node
       
  3523     p->ref.deref();
       
  3524     return p;
       
  3525 }
       
  3526 
       
  3527 QDomNodePrivate* QDomDocumentTypePrivate::insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild)
       
  3528 {
       
  3529     // Call the origianl implementation
       
  3530     QDomNodePrivate* p = QDomNodePrivate::insertBefore(newChild, refChild);
       
  3531     // Update the maps
       
  3532     if (p && p->isEntity())
       
  3533         entities->map.insertMulti(p->nodeName(), p);
       
  3534     else if (p && p->isNotation())
       
  3535         notations->map.insertMulti(p->nodeName(), p);
       
  3536 
       
  3537     return p;
       
  3538 }
       
  3539 
       
  3540 QDomNodePrivate* QDomDocumentTypePrivate::insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild)
       
  3541 {
       
  3542     // Call the origianl implementation
       
  3543     QDomNodePrivate* p = QDomNodePrivate::insertAfter(newChild, refChild);
       
  3544     // Update the maps
       
  3545     if (p && p->isEntity())
       
  3546         entities->map.insertMulti(p->nodeName(), p);
       
  3547     else if (p && p->isNotation())
       
  3548         notations->map.insertMulti(p->nodeName(), p);
       
  3549 
       
  3550     return p;
       
  3551 }
       
  3552 
       
  3553 QDomNodePrivate* QDomDocumentTypePrivate::replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild)
       
  3554 {
       
  3555     // Call the origianl implementation
       
  3556     QDomNodePrivate* p = QDomNodePrivate::replaceChild(newChild, oldChild);
       
  3557     // Update the maps
       
  3558     if (p) {
       
  3559         if (oldChild && oldChild->isEntity())
       
  3560             entities->map.remove(oldChild->nodeName());
       
  3561         else if (oldChild && oldChild->isNotation())
       
  3562             notations->map.remove(oldChild->nodeName());
       
  3563 
       
  3564         if (p->isEntity())
       
  3565             entities->map.insertMulti(p->nodeName(), p);
       
  3566         else if (p->isNotation())
       
  3567             notations->map.insertMulti(p->nodeName(), p);
       
  3568     }
       
  3569 
       
  3570     return p;
       
  3571 }
       
  3572 
       
  3573 QDomNodePrivate* QDomDocumentTypePrivate::removeChild(QDomNodePrivate* oldChild)
       
  3574 {
       
  3575     // Call the origianl implementation
       
  3576     QDomNodePrivate* p = QDomNodePrivate::removeChild( oldChild);
       
  3577     // Update the maps
       
  3578     if (p && p->isEntity())
       
  3579         entities->map.remove(p->nodeName());
       
  3580     else if (p && p->isNotation())
       
  3581         notations->map.remove(p ->nodeName());
       
  3582 
       
  3583     return p;
       
  3584 }
       
  3585 
       
  3586 QDomNodePrivate* QDomDocumentTypePrivate::appendChild(QDomNodePrivate* newChild)
       
  3587 {
       
  3588     return insertAfter(newChild, 0);
       
  3589 }
       
  3590 
       
  3591 static QString quotedValue(const QString &data)
       
  3592 {
       
  3593     QChar quote = data.indexOf(QLatin1Char('\'')) == -1
       
  3594                     ? QLatin1Char('\'')
       
  3595                     : QLatin1Char('"');
       
  3596     return quote + data + quote;
       
  3597 }
       
  3598 
       
  3599 void QDomDocumentTypePrivate::save(QTextStream& s, int, int indent) const
       
  3600 {
       
  3601     if (name.isEmpty())
       
  3602         return;
       
  3603 
       
  3604     s << "<!DOCTYPE " << name;
       
  3605 
       
  3606     if (!publicId.isNull()) {
       
  3607         s << " PUBLIC " << quotedValue(publicId);
       
  3608         if (!systemId.isNull()) {
       
  3609             s << ' ' << quotedValue(systemId);
       
  3610         }
       
  3611     } else if (!systemId.isNull()) {
       
  3612         s << " SYSTEM " << quotedValue(systemId);
       
  3613     }
       
  3614 
       
  3615     if (entities->length()>0 || notations->length()>0) {
       
  3616         s << " [" << endl;
       
  3617 
       
  3618         QHash<QString, QDomNodePrivate *>::const_iterator it2 = notations->map.constBegin();
       
  3619         for (; it2 != notations->map.constEnd(); ++it2)
       
  3620             (*it2)->save(s, 0, indent);
       
  3621 
       
  3622         QHash<QString, QDomNodePrivate *>::const_iterator it = entities->map.constBegin();
       
  3623         for (; it != entities->map.constEnd(); ++it)
       
  3624             (*it)->save(s, 0, indent);
       
  3625 
       
  3626         s << ']';
       
  3627     }
       
  3628 
       
  3629     s << '>' << endl;
       
  3630 }
       
  3631 
       
  3632 /**************************************************************
       
  3633  *
       
  3634  * QDomDocumentType
       
  3635  *
       
  3636  **************************************************************/
       
  3637 
       
  3638 #define IMPL ((QDomDocumentTypePrivate*)impl)
       
  3639 
       
  3640 /*!
       
  3641     \class QDomDocumentType
       
  3642     \reentrant
       
  3643     \brief The QDomDocumentType class is the representation of the DTD
       
  3644     in the document tree.
       
  3645 
       
  3646     \inmodule QtXml
       
  3647     \ingroup xml-tools
       
  3648 
       
  3649     The QDomDocumentType class allows read-only access to some of the
       
  3650     data structures in the DTD: it can return a map of all entities()
       
  3651     and notations(). In addition the function name() returns the name
       
  3652     of the document type as specified in the &lt;!DOCTYPE name&gt;
       
  3653     tag. This class also provides the publicId(), systemId() and
       
  3654     internalSubset() functions.
       
  3655 
       
  3656     \sa QDomDocument
       
  3657 */
       
  3658 
       
  3659 /*!
       
  3660     Creates an empty QDomDocumentType object.
       
  3661 */
       
  3662 QDomDocumentType::QDomDocumentType() : QDomNode()
       
  3663 {
       
  3664 }
       
  3665 
       
  3666 /*!
       
  3667     Constructs a copy of \a n.
       
  3668 
       
  3669     The data of the copy is shared (shallow copy): modifying one node
       
  3670     will also change the other. If you want to make a deep copy, use
       
  3671     cloneNode().
       
  3672 */
       
  3673 QDomDocumentType::QDomDocumentType(const QDomDocumentType& n)
       
  3674     : QDomNode(n)
       
  3675 {
       
  3676 }
       
  3677 
       
  3678 QDomDocumentType::QDomDocumentType(QDomDocumentTypePrivate* n)
       
  3679     : QDomNode(n)
       
  3680 {
       
  3681 }
       
  3682 
       
  3683 /*!
       
  3684     Assigns \a n to this document type.
       
  3685 
       
  3686     The data of the copy is shared (shallow copy): modifying one node
       
  3687     will also change the other. If you want to make a deep copy, use
       
  3688     cloneNode().
       
  3689 */
       
  3690 QDomDocumentType& QDomDocumentType::operator= (const QDomDocumentType& n)
       
  3691 {
       
  3692     return (QDomDocumentType&) QDomNode::operator=(n);
       
  3693 }
       
  3694 
       
  3695 /*!
       
  3696     Returns the name of the document type as specified in the
       
  3697     &lt;!DOCTYPE name&gt; tag.
       
  3698 
       
  3699     \sa nodeName()
       
  3700 */
       
  3701 QString QDomDocumentType::name() const
       
  3702 {
       
  3703     if (!impl)
       
  3704         return QString();
       
  3705     return IMPL->nodeName();
       
  3706 }
       
  3707 
       
  3708 /*!
       
  3709     Returns a map of all entities described in the DTD.
       
  3710 */
       
  3711 QDomNamedNodeMap QDomDocumentType::entities() const
       
  3712 {
       
  3713     if (!impl)
       
  3714         return QDomNamedNodeMap();
       
  3715     return QDomNamedNodeMap(IMPL->entities);
       
  3716 }
       
  3717 
       
  3718 /*!
       
  3719     Returns a map of all notations described in the DTD.
       
  3720 */
       
  3721 QDomNamedNodeMap QDomDocumentType::notations() const
       
  3722 {
       
  3723     if (!impl)
       
  3724         return QDomNamedNodeMap();
       
  3725     return QDomNamedNodeMap(IMPL->notations);
       
  3726 }
       
  3727 
       
  3728 /*!
       
  3729     Returns the public identifier of the external DTD subset or
       
  3730     an empty string if there is no public identifier.
       
  3731 
       
  3732     \sa systemId() internalSubset() QDomImplementation::createDocumentType()
       
  3733 */
       
  3734 QString QDomDocumentType::publicId() const
       
  3735 {
       
  3736     if (!impl)
       
  3737         return QString();
       
  3738     return IMPL->publicId;
       
  3739 }
       
  3740 
       
  3741 /*!
       
  3742     Returns the system identifier of the external DTD subset or
       
  3743     an empty string if there is no system identifier.
       
  3744 
       
  3745     \sa publicId() internalSubset() QDomImplementation::createDocumentType()
       
  3746 */
       
  3747 QString QDomDocumentType::systemId() const
       
  3748 {
       
  3749     if (!impl)
       
  3750         return QString();
       
  3751     return IMPL->systemId;
       
  3752 }
       
  3753 
       
  3754 /*!
       
  3755     Returns the internal subset of the document type or an empty
       
  3756     string if there is no internal subset.
       
  3757 
       
  3758     \sa publicId() systemId()
       
  3759 */
       
  3760 QString QDomDocumentType::internalSubset() const
       
  3761 {
       
  3762     if (!impl)
       
  3763         return QString();
       
  3764     return IMPL->internalSubset;
       
  3765 }
       
  3766 
       
  3767 /*
       
  3768     Are these needed at all? The only difference when removing these
       
  3769     two methods in all subclasses is that we'd get a different type
       
  3770     for null nodes.
       
  3771 */
       
  3772 
       
  3773 /*!
       
  3774     \fn QDomNode::NodeType QDomDocumentType::nodeType() const
       
  3775 
       
  3776     Returns \c DocumentTypeNode.
       
  3777 
       
  3778     \sa isDocumentType() QDomNode::toDocumentType()
       
  3779 */
       
  3780 
       
  3781 #undef IMPL
       
  3782 
       
  3783 /**************************************************************
       
  3784  *
       
  3785  * QDomDocumentFragmentPrivate
       
  3786  *
       
  3787  **************************************************************/
       
  3788 
       
  3789 QDomDocumentFragmentPrivate::QDomDocumentFragmentPrivate(QDomDocumentPrivate* doc, QDomNodePrivate* parent)
       
  3790     : QDomNodePrivate(doc, parent)
       
  3791 {
       
  3792     name = QLatin1String("#document-fragment");
       
  3793 }
       
  3794 
       
  3795 QDomDocumentFragmentPrivate::QDomDocumentFragmentPrivate(QDomNodePrivate* n, bool deep)
       
  3796     : QDomNodePrivate(n, deep)
       
  3797 {
       
  3798 }
       
  3799 
       
  3800 QDomNodePrivate* QDomDocumentFragmentPrivate::cloneNode(bool deep)
       
  3801 {
       
  3802     QDomNodePrivate* p = new QDomDocumentFragmentPrivate(this, deep);
       
  3803     // We are not interested in this node
       
  3804     p->ref.deref();
       
  3805     return p;
       
  3806 }
       
  3807 
       
  3808 /**************************************************************
       
  3809  *
       
  3810  * QDomDocumentFragment
       
  3811  *
       
  3812  **************************************************************/
       
  3813 
       
  3814 /*!
       
  3815     \class QDomDocumentFragment
       
  3816     \reentrant
       
  3817     \brief The QDomDocumentFragment class is a tree of QDomNodes which is not usually a complete QDomDocument.
       
  3818 
       
  3819     \inmodule QtXml
       
  3820     \ingroup xml-tools
       
  3821 
       
  3822     If you want to do complex tree operations it is useful to have a
       
  3823     lightweight class to store nodes and their relations.
       
  3824     QDomDocumentFragment stores a subtree of a document which does not
       
  3825     necessarily represent a well-formed XML document.
       
  3826 
       
  3827     QDomDocumentFragment is also useful if you want to group several
       
  3828     nodes in a list and insert them all together as children of some
       
  3829     node. In these cases QDomDocumentFragment can be used as a
       
  3830     temporary container for this list of children.
       
  3831 
       
  3832     The most important feature of QDomDocumentFragment is that it is
       
  3833     treated in a special way by QDomNode::insertAfter(),
       
  3834     QDomNode::insertBefore(), QDomNode::replaceChild() and
       
  3835     QDomNode::appendChild(): instead of inserting the fragment itself, all
       
  3836     the fragment's children are inserted.
       
  3837 */
       
  3838 
       
  3839 /*!
       
  3840     Constructs an empty document fragment.
       
  3841 */
       
  3842 QDomDocumentFragment::QDomDocumentFragment()
       
  3843 {
       
  3844 }
       
  3845 
       
  3846 QDomDocumentFragment::QDomDocumentFragment(QDomDocumentFragmentPrivate* n)
       
  3847     : QDomNode(n)
       
  3848 {
       
  3849 }
       
  3850 
       
  3851 /*!
       
  3852     Constructs a copy of \a x.
       
  3853 
       
  3854     The data of the copy is shared (shallow copy): modifying one node
       
  3855     will also change the other. If you want to make a deep copy, use
       
  3856     cloneNode().
       
  3857 */
       
  3858 QDomDocumentFragment::QDomDocumentFragment(const QDomDocumentFragment& x)
       
  3859     : QDomNode(x)
       
  3860 {
       
  3861 }
       
  3862 
       
  3863 /*!
       
  3864     Assigns \a x to this DOM document fragment.
       
  3865 
       
  3866     The data of the copy is shared (shallow copy): modifying one node
       
  3867     will also change the other. If you want to make a deep copy, use
       
  3868     cloneNode().
       
  3869 */
       
  3870 QDomDocumentFragment& QDomDocumentFragment::operator= (const QDomDocumentFragment& x)
       
  3871 {
       
  3872     return (QDomDocumentFragment&) QDomNode::operator=(x);
       
  3873 }
       
  3874 
       
  3875 /*!
       
  3876     \fn QDomNode::NodeType QDomDocumentFragment::nodeType() const
       
  3877 
       
  3878     Returns \c DocumentFragment.
       
  3879 
       
  3880     \sa isDocumentFragment() QDomNode::toDocumentFragment()
       
  3881 */
       
  3882 
       
  3883 /**************************************************************
       
  3884  *
       
  3885  * QDomCharacterDataPrivate
       
  3886  *
       
  3887  **************************************************************/
       
  3888 
       
  3889 QDomCharacterDataPrivate::QDomCharacterDataPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p,
       
  3890                                                       const QString& data)
       
  3891     : QDomNodePrivate(d, p)
       
  3892 {
       
  3893     value = data;
       
  3894     name = QLatin1String("#character-data");
       
  3895 }
       
  3896 
       
  3897 QDomCharacterDataPrivate::QDomCharacterDataPrivate(QDomCharacterDataPrivate* n, bool deep)
       
  3898     : QDomNodePrivate(n, deep)
       
  3899 {
       
  3900 }
       
  3901 
       
  3902 QDomNodePrivate* QDomCharacterDataPrivate::cloneNode(bool deep)
       
  3903 {
       
  3904     QDomNodePrivate* p = new QDomCharacterDataPrivate(this, deep);
       
  3905     // We are not interested in this node
       
  3906     p->ref.deref();
       
  3907     return p;
       
  3908 }
       
  3909 
       
  3910 uint QDomCharacterDataPrivate::dataLength() const
       
  3911 {
       
  3912     return value.length();
       
  3913 }
       
  3914 
       
  3915 QString QDomCharacterDataPrivate::substringData(unsigned long offset, unsigned long n) const
       
  3916 {
       
  3917     return value.mid(offset, n);
       
  3918 }
       
  3919 
       
  3920 void QDomCharacterDataPrivate::insertData(unsigned long offset, const QString& arg)
       
  3921 {
       
  3922     value.insert(offset, arg);
       
  3923 }
       
  3924 
       
  3925 void QDomCharacterDataPrivate::deleteData(unsigned long offset, unsigned long n)
       
  3926 {
       
  3927     value.remove(offset, n);
       
  3928 }
       
  3929 
       
  3930 void QDomCharacterDataPrivate::replaceData(unsigned long offset, unsigned long n, const QString& arg)
       
  3931 {
       
  3932     value.replace(offset, n, arg);
       
  3933 }
       
  3934 
       
  3935 void QDomCharacterDataPrivate::appendData(const QString& arg)
       
  3936 {
       
  3937     value += arg;
       
  3938 }
       
  3939 
       
  3940 /**************************************************************
       
  3941  *
       
  3942  * QDomCharacterData
       
  3943  *
       
  3944  **************************************************************/
       
  3945 
       
  3946 #define IMPL ((QDomCharacterDataPrivate*)impl)
       
  3947 
       
  3948 /*!
       
  3949     \class QDomCharacterData
       
  3950     \reentrant
       
  3951     \brief The QDomCharacterData class represents a generic string in the DOM.
       
  3952 
       
  3953     \inmodule QtXml
       
  3954     \ingroup xml-tools
       
  3955 
       
  3956     Character data as used in XML specifies a generic data string.
       
  3957     More specialized versions of this class are QDomText, QDomComment
       
  3958     and QDomCDATASection.
       
  3959 
       
  3960     The data string is set with setData() and retrieved with data().
       
  3961     You can retrieve a portion of the data string using
       
  3962     substringData(). Extra data can be appended with appendData(), or
       
  3963     inserted with insertData(). Portions of the data string can be
       
  3964     deleted with deleteData() or replaced with replaceData(). The
       
  3965     length of the data string is returned by length().
       
  3966 
       
  3967     The node type of the node containing this character data is
       
  3968     returned by nodeType().
       
  3969 
       
  3970     \sa QDomText QDomComment QDomCDATASection
       
  3971 */
       
  3972 
       
  3973 /*!
       
  3974     Constructs an empty character data object.
       
  3975 */
       
  3976 QDomCharacterData::QDomCharacterData()
       
  3977 {
       
  3978 }
       
  3979 
       
  3980 /*!
       
  3981     Constructs a copy of \a x.
       
  3982 
       
  3983     The data of the copy is shared (shallow copy): modifying one node
       
  3984     will also change the other. If you want to make a deep copy, use
       
  3985     cloneNode().
       
  3986 */
       
  3987 QDomCharacterData::QDomCharacterData(const QDomCharacterData& x)
       
  3988     : QDomNode(x)
       
  3989 {
       
  3990 }
       
  3991 
       
  3992 QDomCharacterData::QDomCharacterData(QDomCharacterDataPrivate* n)
       
  3993     : QDomNode(n)
       
  3994 {
       
  3995 }
       
  3996 
       
  3997 /*!
       
  3998     Assigns \a x to this character data.
       
  3999 
       
  4000     The data of the copy is shared (shallow copy): modifying one node
       
  4001     will also change the other. If you want to make a deep copy, use
       
  4002     cloneNode().
       
  4003 */
       
  4004 QDomCharacterData& QDomCharacterData::operator= (const QDomCharacterData& x)
       
  4005 {
       
  4006     return (QDomCharacterData&) QDomNode::operator=(x);
       
  4007 }
       
  4008 
       
  4009 /*!
       
  4010     Returns the string stored in this object.
       
  4011 
       
  4012     If the node is a \link isNull() null node\endlink, it will return
       
  4013     an empty string.
       
  4014 */
       
  4015 QString QDomCharacterData::data() const
       
  4016 {
       
  4017     if (!impl)
       
  4018         return QString();
       
  4019     return impl->nodeValue();
       
  4020 }
       
  4021 
       
  4022 /*!
       
  4023     Sets this object's string to \a v.
       
  4024 */
       
  4025 void QDomCharacterData::setData(const QString& v)
       
  4026 {
       
  4027     if (impl)
       
  4028         impl->setNodeValue(v);
       
  4029 }
       
  4030 
       
  4031 /*!
       
  4032     Returns the length of the stored string.
       
  4033 */
       
  4034 uint QDomCharacterData::length() const
       
  4035 {
       
  4036     if (impl)
       
  4037         return IMPL->dataLength();
       
  4038     return 0;
       
  4039 }
       
  4040 
       
  4041 /*!
       
  4042     Returns the substring of length \a count from position \a offset.
       
  4043 */
       
  4044 QString QDomCharacterData::substringData(unsigned long offset, unsigned long count)
       
  4045 {
       
  4046     if (!impl)
       
  4047         return QString();
       
  4048     return IMPL->substringData(offset, count);
       
  4049 }
       
  4050 
       
  4051 /*!
       
  4052     Appends the string \a arg to the stored string.
       
  4053 */
       
  4054 void QDomCharacterData::appendData(const QString& arg)
       
  4055 {
       
  4056     if (impl)
       
  4057         IMPL->appendData(arg);
       
  4058 }
       
  4059 
       
  4060 /*!
       
  4061     Inserts the string \a arg into the stored string at position \a offset.
       
  4062 */
       
  4063 void QDomCharacterData::insertData(unsigned long offset, const QString& arg)
       
  4064 {
       
  4065     if (impl)
       
  4066         IMPL->insertData(offset, arg);
       
  4067 }
       
  4068 
       
  4069 /*!
       
  4070     Deletes a substring of length \a count from position \a offset.
       
  4071 */
       
  4072 void QDomCharacterData::deleteData(unsigned long offset, unsigned long count)
       
  4073 {
       
  4074     if (impl)
       
  4075         IMPL->deleteData(offset, count);
       
  4076 }
       
  4077 
       
  4078 /*!
       
  4079     Replaces the substring of length \a count starting at position \a
       
  4080     offset with the string \a arg.
       
  4081 */
       
  4082 void QDomCharacterData::replaceData(unsigned long offset, unsigned long count, const QString& arg)
       
  4083 {
       
  4084     if (impl)
       
  4085         IMPL->replaceData(offset, count, arg);
       
  4086 }
       
  4087 
       
  4088 /*!
       
  4089     Returns the type of node this object refers to (i.e. \c TextNode,
       
  4090     \c CDATASectionNode, \c CommentNode or \c CharacterDataNode). For
       
  4091     a \link isNull() null node\endlink, returns \c CharacterDataNode.
       
  4092 */
       
  4093 QDomNode::NodeType QDomCharacterData::nodeType() const
       
  4094 {
       
  4095     if (!impl)
       
  4096         return CharacterDataNode;
       
  4097     return QDomNode::nodeType();
       
  4098 }
       
  4099 
       
  4100 #undef IMPL
       
  4101 
       
  4102 /**************************************************************
       
  4103  *
       
  4104  * QDomAttrPrivate
       
  4105  *
       
  4106  **************************************************************/
       
  4107 
       
  4108 QDomAttrPrivate::QDomAttrPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& name_)
       
  4109     : QDomNodePrivate(d, parent)
       
  4110 {
       
  4111     name = name_;
       
  4112     m_specified = false;
       
  4113 }
       
  4114 
       
  4115 QDomAttrPrivate::QDomAttrPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p, const QString& nsURI, const QString& qName)
       
  4116     : QDomNodePrivate(d, p)
       
  4117 {
       
  4118     qt_split_namespace(prefix, name, qName, !nsURI.isNull());
       
  4119     namespaceURI = nsURI;
       
  4120     createdWithDom1Interface = false;
       
  4121     m_specified = false;
       
  4122 }
       
  4123 
       
  4124 QDomAttrPrivate::QDomAttrPrivate(QDomAttrPrivate* n, bool deep)
       
  4125     : QDomNodePrivate(n, deep)
       
  4126 {
       
  4127     m_specified = n->specified();
       
  4128 }
       
  4129 
       
  4130 void QDomAttrPrivate::setNodeValue(const QString& v)
       
  4131 {
       
  4132     value = v;
       
  4133     QDomTextPrivate *t = new QDomTextPrivate(0, this, v);
       
  4134     // keep the refcount balanced: appendChild() does a ref anyway.
       
  4135     t->ref.deref();
       
  4136     if (first) {
       
  4137         delete removeChild(first);
       
  4138     }
       
  4139     appendChild(t);
       
  4140 }
       
  4141 
       
  4142 QDomNodePrivate* QDomAttrPrivate::cloneNode(bool deep)
       
  4143 {
       
  4144     QDomNodePrivate* p = new QDomAttrPrivate(this, deep);
       
  4145     // We are not interested in this node
       
  4146     p->ref.deref();
       
  4147     return p;
       
  4148 }
       
  4149 
       
  4150 bool QDomAttrPrivate::specified() const
       
  4151 {
       
  4152     return m_specified;
       
  4153 }
       
  4154 
       
  4155 /* \internal
       
  4156   Encode & escape \a str. Yes, it makes no sense to return a QString,
       
  4157   but is so for legacy reasons.
       
  4158 
       
  4159   Remember that content produced should be able to roundtrip with 2.11 End-of-Line Handling
       
  4160   and 3.3.3 Attribute-Value Normalization.
       
  4161 
       
  4162   If \a performAVN is true, characters will be escaped to survive Attribute Value Normalization.
       
  4163   If \a encodeEOLs is true, characters will be escaped to survive End-of-Line Handling.
       
  4164 */
       
  4165 static QString encodeText(const QString &str,
       
  4166                           QTextStream &s,
       
  4167                           const bool encodeQuotes = true,
       
  4168                           const bool performAVN = false,
       
  4169                           const bool encodeEOLs = false)
       
  4170 {
       
  4171 #ifdef QT_NO_TEXTCODEC
       
  4172     Q_UNUSED(s);
       
  4173 #else
       
  4174     const QTextCodec *const codec = s.codec();
       
  4175     Q_ASSERT(codec);
       
  4176 #endif
       
  4177     QString retval(str);
       
  4178     int len = retval.length();
       
  4179     int i = 0;
       
  4180 
       
  4181     while (i < len) {
       
  4182         const QChar ati(retval.at(i));
       
  4183 
       
  4184         if (ati == QLatin1Char('<')) {
       
  4185             retval.replace(i, 1, QLatin1String("&lt;"));
       
  4186             len += 3;
       
  4187             i += 4;
       
  4188         } else if (encodeQuotes && (ati == QLatin1Char('"'))) {
       
  4189             retval.replace(i, 1, QLatin1String("&quot;"));
       
  4190             len += 5;
       
  4191             i += 6;
       
  4192         } else if (ati == QLatin1Char('&')) {
       
  4193             retval.replace(i, 1, QLatin1String("&amp;"));
       
  4194             len += 4;
       
  4195             i += 5;
       
  4196         } else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']')) {
       
  4197             retval.replace(i, 1, QLatin1String("&gt;"));
       
  4198             len += 3;
       
  4199             i += 4;
       
  4200         } else if (performAVN &&
       
  4201                    (ati == QChar(0xA) ||
       
  4202                     ati == QChar(0xD) ||
       
  4203                     ati == QChar(0x9))) {
       
  4204             const QString replacement(QLatin1String("&#x") + QString::number(ati.unicode(), 16) + QLatin1Char(';'));
       
  4205             retval.replace(i, 1, replacement);
       
  4206             i += replacement.length();
       
  4207             len += replacement.length() - 1;
       
  4208         } else if (encodeEOLs && ati == QChar(0xD)) {
       
  4209             retval.replace(i, 1, QLatin1String("&#xd;")); // Replace a single 0xD with a ref for 0xD
       
  4210             len += 4;
       
  4211             i += 5;
       
  4212         } else {
       
  4213 #ifndef QT_NO_TEXTCODEC
       
  4214             if(codec->canEncode(ati))
       
  4215                 ++i;
       
  4216             else
       
  4217 #endif
       
  4218             {
       
  4219                 // We have to use a character reference to get it through.
       
  4220                 const ushort codepoint(ati.unicode());
       
  4221                 const QString replacement(QLatin1String("&#x") + QString::number(codepoint, 16) + QLatin1Char(';'));
       
  4222                 retval.replace(i, 1, replacement);
       
  4223                 i += replacement.length();
       
  4224                 len += replacement.length() - 1;
       
  4225             }
       
  4226         }
       
  4227     }
       
  4228 
       
  4229     return retval;
       
  4230 }
       
  4231 
       
  4232 void QDomAttrPrivate::save(QTextStream& s, int, int) const
       
  4233 {
       
  4234     if (namespaceURI.isNull()) {
       
  4235         s << name << "=\"" << encodeText(value, s, true, true) << '\"';
       
  4236     } else {
       
  4237         s << prefix << ':' << name << "=\"" << encodeText(value, s, true, true) << '\"';
       
  4238         /* This is a fix for 138243, as good as it gets.
       
  4239          *
       
  4240          * QDomElementPrivate::save() output a namespace declaration if
       
  4241          * the element is in a namespace, no matter what. This function do as well, meaning
       
  4242          * that we get two identical namespace declaration if we don't have the if-
       
  4243          * statement below.
       
  4244          *
       
  4245          * This doesn't work when the parent element has the same prefix as us but
       
  4246          * a different namespace. However, this can only occur by the user modifying the element,
       
  4247          * and we don't do fixups by that anyway, and hence it's the user responsibility to not
       
  4248          * arrive in those situations. */
       
  4249         if(!ownerNode ||
       
  4250            ownerNode->prefix != prefix) {
       
  4251             s << " xmlns:" << prefix << "=\"" << encodeText(namespaceURI, s, true, true) << '\"';
       
  4252         }
       
  4253     }
       
  4254 }
       
  4255 
       
  4256 /**************************************************************
       
  4257  *
       
  4258  * QDomAttr
       
  4259  *
       
  4260  **************************************************************/
       
  4261 
       
  4262 #define IMPL ((QDomAttrPrivate*)impl)
       
  4263 
       
  4264 /*!
       
  4265     \class QDomAttr
       
  4266     \reentrant
       
  4267     \brief The QDomAttr class represents one attribute of a QDomElement.
       
  4268 
       
  4269     \inmodule QtXml
       
  4270     \ingroup xml-tools
       
  4271 
       
  4272     For example, the following piece of XML produces an element with
       
  4273     no children, but two attributes:
       
  4274 
       
  4275     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 7
       
  4276 
       
  4277     You can access the attributes of an element with code like this:
       
  4278 
       
  4279     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 8
       
  4280 
       
  4281     This example also shows that changing an attribute received from
       
  4282     an element changes the attribute of the element. If you do not
       
  4283     want to change the value of the element's attribute you must
       
  4284     use cloneNode() to get an independent copy of the attribute.
       
  4285 
       
  4286     QDomAttr can return the name() and value() of an attribute. An
       
  4287     attribute's value is set with setValue(). If specified() returns
       
  4288     true the value was set with setValue(). The node this
       
  4289     attribute is attached to (if any) is returned by ownerElement().
       
  4290 
       
  4291     For further information about the Document Object Model see
       
  4292     \l{http://www.w3.org/TR/REC-DOM-Level-1/} and
       
  4293     \l{http://www.w3.org/TR/DOM-Level-2-Core/}.
       
  4294     For a more general introduction of the DOM implementation see the
       
  4295     QDomDocument documentation.
       
  4296 */
       
  4297 
       
  4298 
       
  4299 /*!
       
  4300     Constructs an empty attribute.
       
  4301 */
       
  4302 QDomAttr::QDomAttr()
       
  4303 {
       
  4304 }
       
  4305 
       
  4306 /*!
       
  4307     Constructs a copy of \a x.
       
  4308 
       
  4309     The data of the copy is shared (shallow copy): modifying one node
       
  4310     will also change the other. If you want to make a deep copy, use
       
  4311     cloneNode().
       
  4312 */
       
  4313 QDomAttr::QDomAttr(const QDomAttr& x)
       
  4314     : QDomNode(x)
       
  4315 {
       
  4316 }
       
  4317 
       
  4318 QDomAttr::QDomAttr(QDomAttrPrivate* n)
       
  4319     : QDomNode(n)
       
  4320 {
       
  4321 }
       
  4322 
       
  4323 /*!
       
  4324     Assigns \a x to this DOM attribute.
       
  4325 
       
  4326     The data of the copy is shared (shallow copy): modifying one node
       
  4327     will also change the other. If you want to make a deep copy, use
       
  4328     cloneNode().
       
  4329 */
       
  4330 QDomAttr& QDomAttr::operator= (const QDomAttr& x)
       
  4331 {
       
  4332     return (QDomAttr&) QDomNode::operator=(x);
       
  4333 }
       
  4334 
       
  4335 /*!
       
  4336     Returns the attribute's name.
       
  4337 */
       
  4338 QString QDomAttr::name() const
       
  4339 {
       
  4340     if (!impl)
       
  4341         return QString();
       
  4342     return impl->nodeName();
       
  4343 }
       
  4344 
       
  4345 /*!
       
  4346     Returns true if the attribute has been set by the user with setValue().
       
  4347     Returns false if the value hasn't been specified or set.
       
  4348 
       
  4349     \sa setValue()
       
  4350 */
       
  4351 bool QDomAttr::specified() const
       
  4352 {
       
  4353     if (!impl)
       
  4354         return false;
       
  4355     return IMPL->specified();
       
  4356 }
       
  4357 
       
  4358 /*!
       
  4359     Returns the element node this attribute is attached to or a \link
       
  4360     QDomNode::isNull() null node\endlink if this attribute is not
       
  4361     attached to any element.
       
  4362 */
       
  4363 QDomElement QDomAttr::ownerElement() const
       
  4364 {
       
  4365     Q_ASSERT(impl->parent());
       
  4366     if (!impl->parent()->isElement())
       
  4367         return QDomElement();
       
  4368     return QDomElement((QDomElementPrivate*)(impl->parent()));
       
  4369 }
       
  4370 
       
  4371 /*!
       
  4372     Returns the value of the attribute or an empty string if the
       
  4373     attribute has not been specified.
       
  4374 
       
  4375     \sa specified() setValue()
       
  4376 */
       
  4377 QString QDomAttr::value() const
       
  4378 {
       
  4379     if (!impl)
       
  4380         return QString();
       
  4381     return impl->nodeValue();
       
  4382 }
       
  4383 
       
  4384 /*!
       
  4385     Sets the attribute's value to \a v.
       
  4386 
       
  4387     \sa value()
       
  4388 */
       
  4389 void QDomAttr::setValue(const QString& v)
       
  4390 {
       
  4391     if (!impl)
       
  4392         return;
       
  4393     impl->setNodeValue(v);
       
  4394     IMPL->m_specified = true;
       
  4395 }
       
  4396 
       
  4397 /*!
       
  4398     \fn QDomNode::NodeType QDomAttr::nodeType() const
       
  4399 
       
  4400     Returns \link QDomNode::NodeType AttributeNode\endlink.
       
  4401 */
       
  4402 
       
  4403 #undef IMPL
       
  4404 
       
  4405 /**************************************************************
       
  4406  *
       
  4407  * QDomElementPrivate
       
  4408  *
       
  4409  **************************************************************/
       
  4410 
       
  4411 QDomElementPrivate::QDomElementPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p,
       
  4412                                           const QString& tagname)
       
  4413     : QDomNodePrivate(d, p)
       
  4414 {
       
  4415     name = tagname;
       
  4416     m_attr = new QDomNamedNodeMapPrivate(this);
       
  4417 }
       
  4418 
       
  4419 QDomElementPrivate::QDomElementPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p,
       
  4420         const QString& nsURI, const QString& qName)
       
  4421     : QDomNodePrivate(d, p)
       
  4422 {
       
  4423     qt_split_namespace(prefix, name, qName, !nsURI.isNull());
       
  4424     namespaceURI = nsURI;
       
  4425     createdWithDom1Interface = false;
       
  4426     m_attr = new QDomNamedNodeMapPrivate(this);
       
  4427 }
       
  4428 
       
  4429 QDomElementPrivate::QDomElementPrivate(QDomElementPrivate* n, bool deep) :
       
  4430     QDomNodePrivate(n, deep)
       
  4431 {
       
  4432     m_attr = n->m_attr->clone(this);
       
  4433     // Reference is down to 0, so we set it to 1 here.
       
  4434     m_attr->ref.ref();
       
  4435 }
       
  4436 
       
  4437 QDomElementPrivate::~QDomElementPrivate()
       
  4438 {
       
  4439     if (!m_attr->ref.deref())
       
  4440         delete m_attr;
       
  4441 }
       
  4442 
       
  4443 QDomNodePrivate* QDomElementPrivate::cloneNode(bool deep)
       
  4444 {
       
  4445     QDomNodePrivate* p = new QDomElementPrivate(this, deep);
       
  4446     // We are not interested in this node
       
  4447     p->ref.deref();
       
  4448     return p;
       
  4449 }
       
  4450 
       
  4451 QString QDomElementPrivate::attribute(const QString& name_, const QString& defValue) const
       
  4452 {
       
  4453     QDomNodePrivate* n = m_attr->namedItem(name_);
       
  4454     if (!n)
       
  4455         return defValue;
       
  4456 
       
  4457     return n->nodeValue();
       
  4458 }
       
  4459 
       
  4460 QString QDomElementPrivate::attributeNS(const QString& nsURI, const QString& localName, const QString& defValue) const
       
  4461 {
       
  4462     QDomNodePrivate* n = m_attr->namedItemNS(nsURI, localName);
       
  4463     if (!n)
       
  4464         return defValue;
       
  4465 
       
  4466     return n->nodeValue();
       
  4467 }
       
  4468 
       
  4469 void QDomElementPrivate::setAttribute(const QString& aname, const QString& newValue)
       
  4470 {
       
  4471     QDomNodePrivate* n = m_attr->namedItem(aname);
       
  4472     if (!n) {
       
  4473         n = new QDomAttrPrivate(ownerDocument(), this, aname);
       
  4474         n->setNodeValue(newValue);
       
  4475 
       
  4476         // Referencing is done by the map, so we set the reference counter back
       
  4477         // to 0 here. This is ok since we created the QDomAttrPrivate.
       
  4478         n->ref.deref();
       
  4479         m_attr->setNamedItem(n);
       
  4480     } else {
       
  4481         n->setNodeValue(newValue);
       
  4482     }
       
  4483 }
       
  4484 
       
  4485 void QDomElementPrivate::setAttributeNS(const QString& nsURI, const QString& qName, const QString& newValue)
       
  4486 {
       
  4487     QString prefix, localName;
       
  4488     qt_split_namespace(prefix, localName, qName, true);
       
  4489     QDomNodePrivate* n = m_attr->namedItemNS(nsURI, localName);
       
  4490     if (!n) {
       
  4491         n = new QDomAttrPrivate(ownerDocument(), this, nsURI, qName);
       
  4492         n->setNodeValue(newValue);
       
  4493 
       
  4494         // Referencing is done by the map, so we set the reference counter back
       
  4495         // to 0 here. This is ok since we created the QDomAttrPrivate.
       
  4496         n->ref.deref();
       
  4497         m_attr->setNamedItem(n);
       
  4498     } else {
       
  4499         n->setNodeValue(newValue);
       
  4500         n->prefix = prefix;
       
  4501     }
       
  4502 }
       
  4503 
       
  4504 void QDomElementPrivate::removeAttribute(const QString& aname)
       
  4505 {
       
  4506     QDomNodePrivate* p = m_attr->removeNamedItem(aname);
       
  4507     if (p && p->ref == 0)
       
  4508         delete p;
       
  4509 }
       
  4510 
       
  4511 QDomAttrPrivate* QDomElementPrivate::attributeNode(const QString& aname)
       
  4512 {
       
  4513     return (QDomAttrPrivate*)m_attr->namedItem(aname);
       
  4514 }
       
  4515 
       
  4516 QDomAttrPrivate* QDomElementPrivate::attributeNodeNS(const QString& nsURI, const QString& localName)
       
  4517 {
       
  4518     return (QDomAttrPrivate*)m_attr->namedItemNS(nsURI, localName);
       
  4519 }
       
  4520 
       
  4521 QDomAttrPrivate* QDomElementPrivate::setAttributeNode(QDomAttrPrivate* newAttr)
       
  4522 {
       
  4523     QDomNodePrivate* n = m_attr->namedItem(newAttr->nodeName());
       
  4524 
       
  4525     // Referencing is done by the maps
       
  4526     m_attr->setNamedItem(newAttr);
       
  4527 
       
  4528     newAttr->setParent(this);
       
  4529 
       
  4530     return (QDomAttrPrivate*)n;
       
  4531 }
       
  4532 
       
  4533 QDomAttrPrivate* QDomElementPrivate::setAttributeNodeNS(QDomAttrPrivate* newAttr)
       
  4534 {
       
  4535     QDomNodePrivate* n = 0;
       
  4536     if (!newAttr->prefix.isNull())
       
  4537         n = m_attr->namedItemNS(newAttr->namespaceURI, newAttr->name);
       
  4538 
       
  4539     // Referencing is done by the maps
       
  4540     m_attr->setNamedItem(newAttr);
       
  4541 
       
  4542     return (QDomAttrPrivate*)n;
       
  4543 }
       
  4544 
       
  4545 QDomAttrPrivate* QDomElementPrivate::removeAttributeNode(QDomAttrPrivate* oldAttr)
       
  4546 {
       
  4547     return (QDomAttrPrivate*)m_attr->removeNamedItem(oldAttr->nodeName());
       
  4548 }
       
  4549 
       
  4550 bool QDomElementPrivate::hasAttribute(const QString& aname)
       
  4551 {
       
  4552     return m_attr->contains(aname);
       
  4553 }
       
  4554 
       
  4555 bool QDomElementPrivate::hasAttributeNS(const QString& nsURI, const QString& localName)
       
  4556 {
       
  4557     return m_attr->containsNS(nsURI, localName);
       
  4558 }
       
  4559 
       
  4560 QString QDomElementPrivate::text()
       
  4561 {
       
  4562     QString t(QLatin1String(""));
       
  4563 
       
  4564     QDomNodePrivate* p = first;
       
  4565     while (p) {
       
  4566         if (p->isText() || p->isCDATASection())
       
  4567             t += p->nodeValue();
       
  4568         else if (p->isElement())
       
  4569             t += ((QDomElementPrivate*)p)->text();
       
  4570         p = p->next;
       
  4571     }
       
  4572 
       
  4573     return t;
       
  4574 }
       
  4575 
       
  4576 void QDomElementPrivate::save(QTextStream& s, int depth, int indent) const
       
  4577 {
       
  4578     if (!(prev && prev->isText()))
       
  4579         s << QString(indent < 1 ? 0 : depth * indent, QLatin1Char(' '));
       
  4580 
       
  4581     QString qName(name);
       
  4582     QString nsDecl(QLatin1String(""));
       
  4583     if (!namespaceURI.isNull()) {
       
  4584         /** ### Qt 5:
       
  4585          *
       
  4586          * If we still have QDom, optimize this so that we only declare namespaces that are not
       
  4587          * yet declared. We loose default namespace mappings, so maybe we should rather store
       
  4588          * the information that we get from startPrefixMapping()/endPrefixMapping() and use them.
       
  4589          * Modifications becomes more complex then, however.
       
  4590          *
       
  4591          * We cannot do this during the Qt 4 series because it would require too invasive changes, and
       
  4592          * hence possibly behavioral changes.
       
  4593          */
       
  4594         if (prefix.isEmpty()) {
       
  4595             nsDecl = QLatin1String(" xmlns");
       
  4596         } else {
       
  4597             qName = prefix + QLatin1Char(':') + name;
       
  4598             nsDecl = QLatin1String(" xmlns:") + prefix;
       
  4599         }
       
  4600         nsDecl += QLatin1String("=\"") + encodeText(namespaceURI, s) + QLatin1Char('\"');
       
  4601     }
       
  4602     s << '<' << qName << nsDecl;
       
  4603 
       
  4604     QSet<QString> outputtedPrefixes;
       
  4605 
       
  4606     /* Write out attributes. */
       
  4607     if (!m_attr->map.isEmpty()) {
       
  4608         QHash<QString, QDomNodePrivate *>::const_iterator it = m_attr->map.constBegin();
       
  4609         for (; it != m_attr->map.constEnd(); ++it) {
       
  4610             s << ' ';
       
  4611             if (it.value()->namespaceURI.isNull()) {
       
  4612                 s << it.value()->name << "=\"" << encodeText(it.value()->value, s, true, true) << '\"';
       
  4613             } else {
       
  4614                 s << it.value()->prefix << ':' << it.value()->name << "=\"" << encodeText(it.value()->value, s, true, true) << '\"';
       
  4615                 /* This is a fix for 138243, as good as it gets.
       
  4616                  *
       
  4617                  * QDomElementPrivate::save() output a namespace declaration if
       
  4618                  * the element is in a namespace, no matter what. This function do as well, meaning
       
  4619                  * that we get two identical namespace declaration if we don't have the if-
       
  4620                  * statement below.
       
  4621                  *
       
  4622                  * This doesn't work when the parent element has the same prefix as us but
       
  4623                  * a different namespace. However, this can only occur by the user modifying the element,
       
  4624                  * and we don't do fixups by that anyway, and hence it's the user responsibility to not
       
  4625                  * arrive in those situations. */
       
  4626                 if((!it.value()->ownerNode ||
       
  4627                    it.value()->ownerNode->prefix != it.value()->prefix) &&
       
  4628                    !outputtedPrefixes.contains(it.value()->prefix)) {
       
  4629                     s << " xmlns:" << it.value()->prefix << "=\"" << encodeText(it.value()->namespaceURI, s, true, true) << '\"';
       
  4630                     outputtedPrefixes.insert(it.value()->prefix);
       
  4631                 }
       
  4632             }
       
  4633         }
       
  4634     }
       
  4635 
       
  4636     if (last) {
       
  4637         // has child nodes
       
  4638         if (first->isText())
       
  4639             s << '>';
       
  4640         else {
       
  4641             s << '>';
       
  4642 
       
  4643             /* -1 disables new lines. */
       
  4644             if (indent != -1)
       
  4645                 s << endl;
       
  4646         }
       
  4647         QDomNodePrivate::save(s, depth + 1, indent); if (!last->isText())
       
  4648             s << QString(indent < 1 ? 0 : depth * indent, QLatin1Char(' '));
       
  4649 
       
  4650         s << "</" << qName << '>';
       
  4651     } else {
       
  4652         s << "/>";
       
  4653     }
       
  4654     if (!(next && next->isText())) {
       
  4655         /* -1 disables new lines. */
       
  4656         if (indent != -1)
       
  4657             s << endl;
       
  4658     }
       
  4659 }
       
  4660 
       
  4661 /**************************************************************
       
  4662  *
       
  4663  * QDomElement
       
  4664  *
       
  4665  **************************************************************/
       
  4666 
       
  4667 #define IMPL ((QDomElementPrivate*)impl)
       
  4668 
       
  4669 /*!
       
  4670     \class QDomElement
       
  4671     \reentrant
       
  4672     \brief The QDomElement class represents one element in the DOM tree.
       
  4673 
       
  4674     \inmodule QtXml
       
  4675     \ingroup xml-tools
       
  4676 
       
  4677     Elements have a tagName() and zero or more attributes associated
       
  4678     with them. The tag name can be changed with setTagName().
       
  4679 
       
  4680     Element attributes are represented by QDomAttr objects that can
       
  4681     be queried using the attribute() and attributeNode() functions.
       
  4682     You can set attributes with the setAttribute() and
       
  4683     setAttributeNode() functions. Attributes can be removed with
       
  4684     removeAttribute(). There are namespace-aware equivalents to these
       
  4685     functions, i.e. setAttributeNS(), setAttributeNodeNS() and
       
  4686     removeAttributeNS().
       
  4687 
       
  4688     If you want to access the text of a node use text(), e.g.
       
  4689     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 9
       
  4690     The text() function operates recursively to find the text (since
       
  4691     not all elements contain text). If you want to find all the text
       
  4692     in all of a node's children, iterate over the children looking for
       
  4693     QDomText nodes, e.g.
       
  4694     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 10
       
  4695     Note that we attempt to convert each node to a text node and use
       
  4696     text() rather than using firstChild().toText().data() or
       
  4697     n.toText().data() directly on the node, because the node may not
       
  4698     be a text element.
       
  4699 
       
  4700     You can get a list of all the decendents of an element which have
       
  4701     a specified tag name with elementsByTagName() or
       
  4702     elementsByTagNameNS().
       
  4703 
       
  4704     To browse the elements of a dom document use firstChildElement(), lastChildElement(),
       
  4705     nextSiblingElement() and previousSiblingElement(). For example, to iterate over all
       
  4706     child elements called "entry" in a root element called "database", you can use:
       
  4707     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 11
       
  4708 
       
  4709     For further information about the Document Object Model see
       
  4710     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  4711     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  4712     For a more general introduction of the DOM implementation see the
       
  4713     QDomDocument documentation.
       
  4714 */
       
  4715 
       
  4716 /*!
       
  4717     Constructs an empty element. Use the QDomDocument::createElement()
       
  4718     function to construct elements with content.
       
  4719 */
       
  4720 QDomElement::QDomElement()
       
  4721     : QDomNode()
       
  4722 {
       
  4723 }
       
  4724 
       
  4725 /*!
       
  4726     Constructs a copy of \a x.
       
  4727 
       
  4728     The data of the copy is shared (shallow copy): modifying one node
       
  4729     will also change the other. If you want to make a deep copy, use
       
  4730     cloneNode().
       
  4731 */
       
  4732 QDomElement::QDomElement(const QDomElement& x)
       
  4733     : QDomNode(x)
       
  4734 {
       
  4735 }
       
  4736 
       
  4737 QDomElement::QDomElement(QDomElementPrivate* n)
       
  4738     : QDomNode(n)
       
  4739 {
       
  4740 }
       
  4741 
       
  4742 /*!
       
  4743     Assigns \a x to this DOM element.
       
  4744 
       
  4745     The data of the copy is shared (shallow copy): modifying one node
       
  4746     will also change the other. If you want to make a deep copy, use
       
  4747     cloneNode().
       
  4748 */
       
  4749 QDomElement& QDomElement::operator= (const QDomElement& x)
       
  4750 {
       
  4751     return (QDomElement&) QDomNode::operator=(x);
       
  4752 }
       
  4753 
       
  4754 /*!
       
  4755     \fn QDomNode::NodeType QDomElement::nodeType() const
       
  4756 
       
  4757     Returns \c ElementNode.
       
  4758 */
       
  4759 
       
  4760 /*!
       
  4761     Sets this element's tag name to \a name.
       
  4762 
       
  4763     \sa tagName()
       
  4764 */
       
  4765 void QDomElement::setTagName(const QString& name)
       
  4766 {
       
  4767     if (impl)
       
  4768         impl->name = name;
       
  4769 }
       
  4770 
       
  4771 /*!
       
  4772     Returns the tag name of this element. For an XML element like this:
       
  4773 
       
  4774     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 12
       
  4775 
       
  4776     the tagname would return "img".
       
  4777 
       
  4778     \sa setTagName()
       
  4779 */
       
  4780 QString QDomElement::tagName() const
       
  4781 {
       
  4782     if (!impl)
       
  4783         return QString();
       
  4784     return impl->nodeName();
       
  4785 }
       
  4786 
       
  4787 
       
  4788 /*!
       
  4789     Returns a QDomNamedNodeMap containing all this element's attributes.
       
  4790 
       
  4791     \sa attribute() setAttribute() attributeNode() setAttributeNode()
       
  4792 */
       
  4793 QDomNamedNodeMap QDomElement::attributes() const
       
  4794 {
       
  4795     if (!impl)
       
  4796         return QDomNamedNodeMap();
       
  4797     return QDomNamedNodeMap(IMPL->attributes());
       
  4798 }
       
  4799 
       
  4800 /*!
       
  4801     Returns the attribute called \a name. If the attribute does not
       
  4802     exist \a defValue is returned.
       
  4803 
       
  4804     \sa setAttribute() attributeNode() setAttributeNode() attributeNS()
       
  4805 */
       
  4806 QString QDomElement::attribute(const QString& name, const QString& defValue) const
       
  4807 {
       
  4808     if (!impl)
       
  4809         return defValue;
       
  4810     return IMPL->attribute(name, defValue);
       
  4811 }
       
  4812 
       
  4813 /*!
       
  4814     Adds an attribute called \a name with value \a value. If an
       
  4815     attribute with the same name exists, its value is replaced by \a
       
  4816     value.
       
  4817 
       
  4818     \sa attribute() setAttributeNode() setAttributeNS()
       
  4819 */
       
  4820 void QDomElement::setAttribute(const QString& name, const QString& value)
       
  4821 {
       
  4822     if (!impl)
       
  4823         return;
       
  4824     IMPL->setAttribute(name, value);
       
  4825 }
       
  4826 
       
  4827 /*!
       
  4828   \fn void QDomElement::setAttribute(const QString& name, int value)
       
  4829 
       
  4830     \overload
       
  4831     The number is formatted according to the current locale.
       
  4832 */
       
  4833 
       
  4834 /*!
       
  4835   \fn void QDomElement::setAttribute(const QString& name, uint value)
       
  4836 
       
  4837     \overload
       
  4838     The number is formatted according to the current locale.
       
  4839 */
       
  4840 
       
  4841 /*!
       
  4842     \overload
       
  4843 
       
  4844     The number is formatted according to the current locale.
       
  4845 */
       
  4846 void QDomElement::setAttribute(const QString& name, qlonglong value)
       
  4847 {
       
  4848     if (!impl)
       
  4849         return;
       
  4850     QString x;
       
  4851     x.setNum(value);
       
  4852     IMPL->setAttribute(name, x);
       
  4853 }
       
  4854 
       
  4855 /*!
       
  4856     \overload
       
  4857 
       
  4858     The number is formatted according to the current locale.
       
  4859 */
       
  4860 void QDomElement::setAttribute(const QString& name, qulonglong value)
       
  4861 {
       
  4862     if (!impl)
       
  4863         return;
       
  4864     QString x;
       
  4865     x.setNum(value);
       
  4866     IMPL->setAttribute(name, x);
       
  4867 }
       
  4868 
       
  4869 /*!
       
  4870     \overload
       
  4871 
       
  4872     The number is formatted according to the current locale.
       
  4873 */
       
  4874 void QDomElement::setAttribute(const QString& name, float value)
       
  4875 {
       
  4876     if (!impl)
       
  4877         return;
       
  4878     QString x;
       
  4879     x.setNum(value);
       
  4880     IMPL->setAttribute(name, x);
       
  4881 }
       
  4882 
       
  4883 /*!
       
  4884     \overload
       
  4885 
       
  4886     The number is formatted according to the current locale.
       
  4887 */
       
  4888 void QDomElement::setAttribute(const QString& name, double value)
       
  4889 {
       
  4890     if (!impl)
       
  4891         return;
       
  4892     QString x;
       
  4893     char buf[256];
       
  4894     int count = qsnprintf(buf, sizeof(buf), "%.16g", value);
       
  4895     if (count > 0)
       
  4896         x = QString::fromLatin1(buf, count);
       
  4897     else
       
  4898         x.setNum(value); // Fallback
       
  4899     IMPL->setAttribute(name, x);
       
  4900 }
       
  4901 
       
  4902 /*!
       
  4903     Removes the attribute called name \a name from this element.
       
  4904 
       
  4905     \sa setAttribute() attribute() removeAttributeNS()
       
  4906 */
       
  4907 void QDomElement::removeAttribute(const QString& name)
       
  4908 {
       
  4909     if (!impl)
       
  4910         return;
       
  4911     IMPL->removeAttribute(name);
       
  4912 }
       
  4913 
       
  4914 /*!
       
  4915     Returns the QDomAttr object that corresponds to the attribute
       
  4916     called \a name. If no such attribute exists a \link
       
  4917     QDomNode::isNull() null attribute\endlink is returned.
       
  4918 
       
  4919     \sa setAttributeNode() attribute() setAttribute() attributeNodeNS()
       
  4920 */
       
  4921 QDomAttr QDomElement::attributeNode(const QString& name)
       
  4922 {
       
  4923     if (!impl)
       
  4924         return QDomAttr();
       
  4925     return QDomAttr(IMPL->attributeNode(name));
       
  4926 }
       
  4927 
       
  4928 /*!
       
  4929     Adds the attribute \a newAttr to this element.
       
  4930 
       
  4931     If the element has another attribute that has the same name as \a
       
  4932     newAttr, this function replaces that attribute and returns it;
       
  4933     otherwise the function returns a \link QDomNode::isNull() null
       
  4934     attribute\endlink.
       
  4935 
       
  4936     \sa attributeNode() setAttribute() setAttributeNodeNS()
       
  4937 */
       
  4938 QDomAttr QDomElement::setAttributeNode(const QDomAttr& newAttr)
       
  4939 {
       
  4940     if (!impl)
       
  4941         return QDomAttr();
       
  4942     return QDomAttr(IMPL->setAttributeNode(((QDomAttrPrivate*)newAttr.impl)));
       
  4943 }
       
  4944 
       
  4945 /*!
       
  4946     Removes the attribute \a oldAttr from the element and returns it.
       
  4947 
       
  4948     \sa attributeNode() setAttributeNode()
       
  4949 */
       
  4950 QDomAttr QDomElement::removeAttributeNode(const QDomAttr& oldAttr)
       
  4951 {
       
  4952     if (!impl)
       
  4953         return QDomAttr(); // ### should this return oldAttr?
       
  4954     return QDomAttr(IMPL->removeAttributeNode(((QDomAttrPrivate*)oldAttr.impl)));
       
  4955 }
       
  4956 
       
  4957 /*!
       
  4958   Returns a QDomNodeList containing all descendants of this element
       
  4959   named \a tagname encountered during a preorder traversal of the
       
  4960   element subtree with this element as its root. The order of the
       
  4961   elements in the returned list is the order they are encountered
       
  4962   during the preorder traversal.
       
  4963 
       
  4964   \sa elementsByTagNameNS() QDomDocument::elementsByTagName()
       
  4965 */
       
  4966 QDomNodeList QDomElement::elementsByTagName(const QString& tagname) const
       
  4967 {
       
  4968     return QDomNodeList(new QDomNodeListPrivate(impl, tagname));
       
  4969 }
       
  4970 
       
  4971 /*!
       
  4972   Returns true if this element has an attribute called \a name;
       
  4973   otherwise returns false.
       
  4974 
       
  4975   \bold{Note:} This function does not take the presence of namespaces
       
  4976   into account.  As a result, the specified name will be tested
       
  4977   against fully-qualified attribute names that include any namespace
       
  4978   prefixes that may be present.
       
  4979 
       
  4980   Use hasAttributeNS() to explicitly test for attributes with specific
       
  4981   namespaces and names.
       
  4982 */
       
  4983 bool QDomElement::hasAttribute(const QString& name) const
       
  4984 {
       
  4985     if (!impl)
       
  4986         return false;
       
  4987     return IMPL->hasAttribute(name);
       
  4988 }
       
  4989 
       
  4990 /*!
       
  4991     Returns the attribute with the local name \a localName and the
       
  4992     namespace URI \a nsURI. If the attribute does not exist \a
       
  4993     defValue is returned.
       
  4994 
       
  4995     \sa setAttributeNS() attributeNodeNS() setAttributeNodeNS() attribute()
       
  4996 */
       
  4997 QString QDomElement::attributeNS(const QString nsURI, const QString& localName, const QString& defValue) const
       
  4998 {
       
  4999     if (!impl)
       
  5000         return defValue;
       
  5001     return IMPL->attributeNS(nsURI, localName, defValue);
       
  5002 }
       
  5003 
       
  5004 /*!
       
  5005     Adds an attribute with the qualified name \a qName and the
       
  5006     namespace URI \a nsURI with the value \a value. If an attribute
       
  5007     with the same local name and namespace URI exists, its prefix is
       
  5008     replaced by the prefix of \a qName and its value is repaced by \a
       
  5009     value.
       
  5010 
       
  5011     Although \a qName is the qualified name, the local name is used to
       
  5012     decide if an existing attribute's value should be replaced.
       
  5013 
       
  5014     \sa attributeNS() setAttributeNodeNS() setAttribute()
       
  5015 */
       
  5016 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, const QString& value)
       
  5017 {
       
  5018     if (!impl)
       
  5019         return;
       
  5020     IMPL->setAttributeNS(nsURI, qName, value);
       
  5021 }
       
  5022 
       
  5023 /*!
       
  5024   \fn void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, int value)
       
  5025 
       
  5026     \overload
       
  5027 */
       
  5028 
       
  5029 /*!
       
  5030   \fn void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, uint value)
       
  5031 
       
  5032     \overload
       
  5033 */
       
  5034 
       
  5035 /*!
       
  5036     \overload
       
  5037 */
       
  5038 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qlonglong value)
       
  5039 {
       
  5040     if (!impl)
       
  5041         return;
       
  5042     QString x;
       
  5043     x.setNum(value);
       
  5044     IMPL->setAttributeNS(nsURI, qName, x);
       
  5045 }
       
  5046 
       
  5047 /*!
       
  5048     \overload
       
  5049 */
       
  5050 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qulonglong value)
       
  5051 {
       
  5052     if (!impl)
       
  5053         return;
       
  5054     QString x;
       
  5055     x.setNum(value);
       
  5056     IMPL->setAttributeNS(nsURI, qName, x);
       
  5057 }
       
  5058 
       
  5059 /*!
       
  5060     \overload
       
  5061 */
       
  5062 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, double value)
       
  5063 {
       
  5064     if (!impl)
       
  5065         return;
       
  5066     QString x;
       
  5067     x.setNum(value);
       
  5068     IMPL->setAttributeNS(nsURI, qName, x);
       
  5069 }
       
  5070 
       
  5071 /*!
       
  5072     Removes the attribute with the local name \a localName and the
       
  5073     namespace URI \a nsURI from this element.
       
  5074 
       
  5075     \sa setAttributeNS() attributeNS() removeAttribute()
       
  5076 */
       
  5077 void QDomElement::removeAttributeNS(const QString& nsURI, const QString& localName)
       
  5078 {
       
  5079     if (!impl)
       
  5080         return;
       
  5081     QDomNodePrivate *n = IMPL->attributeNodeNS(nsURI, localName);
       
  5082     if (!n)
       
  5083         return;
       
  5084     IMPL->removeAttribute(n->nodeName());
       
  5085 }
       
  5086 
       
  5087 /*!
       
  5088     Returns the QDomAttr object that corresponds to the attribute
       
  5089     with the local name \a localName and the namespace URI \a nsURI.
       
  5090     If no such attribute exists a \l{QDomNode::isNull()}{null
       
  5091     attribute} is returned.
       
  5092 
       
  5093     \sa setAttributeNode() attribute() setAttribute()
       
  5094 */
       
  5095 QDomAttr QDomElement::attributeNodeNS(const QString& nsURI, const QString& localName)
       
  5096 {
       
  5097     if (!impl)
       
  5098         return QDomAttr();
       
  5099     return QDomAttr(IMPL->attributeNodeNS(nsURI, localName));
       
  5100 }
       
  5101 
       
  5102 /*!
       
  5103     Adds the attribute \a newAttr to this element.
       
  5104 
       
  5105     If the element has another attribute that has the same local name
       
  5106     and namespace URI as \a newAttr, this function replaces that
       
  5107     attribute and returns it; otherwise the function returns a \link
       
  5108     QDomNode::isNull() null attribute\endlink.
       
  5109 
       
  5110     \sa attributeNodeNS() setAttributeNS() setAttributeNode()
       
  5111 */
       
  5112 QDomAttr QDomElement::setAttributeNodeNS(const QDomAttr& newAttr)
       
  5113 {
       
  5114     if (!impl)
       
  5115         return QDomAttr();
       
  5116     return QDomAttr(IMPL->setAttributeNodeNS(((QDomAttrPrivate*)newAttr.impl)));
       
  5117 }
       
  5118 
       
  5119 /*!
       
  5120   Returns a QDomNodeList containing all descendants of this element
       
  5121   with local name \a localName and namespace URI \a nsURI encountered
       
  5122   during a preorder traversal of the element subtree with this element
       
  5123   as its root. The order of the elements in the returned list is the
       
  5124   order they are encountered during the preorder traversal.
       
  5125 
       
  5126   \sa elementsByTagName() QDomDocument::elementsByTagNameNS()
       
  5127 */
       
  5128 QDomNodeList QDomElement::elementsByTagNameNS(const QString& nsURI, const QString& localName) const
       
  5129 {
       
  5130     return QDomNodeList(new QDomNodeListPrivate(impl, nsURI, localName));
       
  5131 }
       
  5132 
       
  5133 /*!
       
  5134     Returns true if this element has an attribute with the local name
       
  5135     \a localName and the namespace URI \a nsURI; otherwise returns
       
  5136     false.
       
  5137 */
       
  5138 bool QDomElement::hasAttributeNS(const QString& nsURI, const QString& localName) const
       
  5139 {
       
  5140     if (!impl)
       
  5141         return false;
       
  5142     return IMPL->hasAttributeNS(nsURI, localName);
       
  5143 }
       
  5144 
       
  5145 /*!
       
  5146     Returns the element's text or an empty string.
       
  5147 
       
  5148     Example:
       
  5149     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 13
       
  5150 
       
  5151     The function text() of the QDomElement for the \c{<h1>} tag,
       
  5152     will return the following text:
       
  5153 
       
  5154     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 14
       
  5155 
       
  5156     Comments are ignored by this function. It only evaluates QDomText
       
  5157     and QDomCDATASection objects.
       
  5158 */
       
  5159 QString QDomElement::text() const
       
  5160 {
       
  5161     if (!impl)
       
  5162         return QString();
       
  5163     return IMPL->text();
       
  5164 }
       
  5165 
       
  5166 #undef IMPL
       
  5167 
       
  5168 /**************************************************************
       
  5169  *
       
  5170  * QDomTextPrivate
       
  5171  *
       
  5172  **************************************************************/
       
  5173 
       
  5174 QDomTextPrivate::QDomTextPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& val)
       
  5175     : QDomCharacterDataPrivate(d, parent, val)
       
  5176 {
       
  5177     name = QLatin1String("#text");
       
  5178 }
       
  5179 
       
  5180 QDomTextPrivate::QDomTextPrivate(QDomTextPrivate* n, bool deep)
       
  5181     : QDomCharacterDataPrivate(n, deep)
       
  5182 {
       
  5183 }
       
  5184 
       
  5185 QDomNodePrivate* QDomTextPrivate::cloneNode(bool deep)
       
  5186 {
       
  5187     QDomNodePrivate* p = new QDomTextPrivate(this, deep);
       
  5188     // We are not interested in this node
       
  5189     p->ref.deref();
       
  5190     return p;
       
  5191 }
       
  5192 
       
  5193 QDomTextPrivate* QDomTextPrivate::splitText(int offset)
       
  5194 {
       
  5195     if (!parent()) {
       
  5196         qWarning("QDomText::splitText  The node has no parent. So I can not split");
       
  5197         return 0;
       
  5198     }
       
  5199 
       
  5200     QDomTextPrivate* t = new QDomTextPrivate(ownerDocument(), 0, value.mid(offset));
       
  5201     value.truncate(offset);
       
  5202 
       
  5203     parent()->insertAfter(t, this);
       
  5204 
       
  5205     return t;
       
  5206 }
       
  5207 
       
  5208 void QDomTextPrivate::save(QTextStream& s, int, int) const
       
  5209 {
       
  5210     QDomTextPrivate *that = const_cast<QDomTextPrivate*>(this);
       
  5211     s << encodeText(value, s, !(that->parent() && that->parent()->isElement()), false, true);
       
  5212 }
       
  5213 
       
  5214 /**************************************************************
       
  5215  *
       
  5216  * QDomText
       
  5217  *
       
  5218  **************************************************************/
       
  5219 
       
  5220 #define IMPL ((QDomTextPrivate*)impl)
       
  5221 
       
  5222 /*!
       
  5223     \class QDomText
       
  5224     \reentrant
       
  5225     \brief The QDomText class represents text data in the parsed XML document.
       
  5226 
       
  5227     \inmodule QtXml
       
  5228     \ingroup xml-tools
       
  5229 
       
  5230     You can split the text in a QDomText object over two QDomText
       
  5231     objecs with splitText().
       
  5232 
       
  5233     For further information about the Document Object Model see
       
  5234     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5235     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5236     For a more general introduction of the DOM implementation see the
       
  5237     QDomDocument documentation.
       
  5238 */
       
  5239 
       
  5240 /*!
       
  5241     Constructs an empty QDomText object.
       
  5242 
       
  5243     To construct a QDomText with content, use QDomDocument::createTextNode().
       
  5244 */
       
  5245 QDomText::QDomText()
       
  5246     : QDomCharacterData()
       
  5247 {
       
  5248 }
       
  5249 
       
  5250 /*!
       
  5251     Constructs a copy of \a x.
       
  5252 
       
  5253     The data of the copy is shared (shallow copy): modifying one node
       
  5254     will also change the other. If you want to make a deep copy, use
       
  5255     cloneNode().
       
  5256 */
       
  5257 QDomText::QDomText(const QDomText& x)
       
  5258     : QDomCharacterData(x)
       
  5259 {
       
  5260 }
       
  5261 
       
  5262 QDomText::QDomText(QDomTextPrivate* n)
       
  5263     : QDomCharacterData(n)
       
  5264 {
       
  5265 }
       
  5266 
       
  5267 /*!
       
  5268     Assigns \a x to this DOM text.
       
  5269 
       
  5270     The data of the copy is shared (shallow copy): modifying one node
       
  5271     will also change the other. If you want to make a deep copy, use
       
  5272     cloneNode().
       
  5273 */
       
  5274 QDomText& QDomText::operator= (const QDomText& x)
       
  5275 {
       
  5276     return (QDomText&) QDomNode::operator=(x);
       
  5277 }
       
  5278 
       
  5279 /*!
       
  5280     \fn QDomNode::NodeType QDomText::nodeType() const
       
  5281 
       
  5282     Returns \c TextNode.
       
  5283 */
       
  5284 
       
  5285 /*!
       
  5286     Splits this DOM text object into two QDomText objects. This object
       
  5287     keeps its first \a offset characters and the second (newly
       
  5288     created) object is inserted into the document tree after this
       
  5289     object with the remaining characters.
       
  5290 
       
  5291     The function returns the newly created object.
       
  5292 
       
  5293     \sa QDomNode::normalize()
       
  5294 */
       
  5295 QDomText QDomText::splitText(int offset)
       
  5296 {
       
  5297     if (!impl)
       
  5298         return QDomText();
       
  5299     return QDomText(IMPL->splitText(offset));
       
  5300 }
       
  5301 
       
  5302 #undef IMPL
       
  5303 
       
  5304 /**************************************************************
       
  5305  *
       
  5306  * QDomCommentPrivate
       
  5307  *
       
  5308  **************************************************************/
       
  5309 
       
  5310 QDomCommentPrivate::QDomCommentPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& val)
       
  5311     : QDomCharacterDataPrivate(d, parent, val)
       
  5312 {
       
  5313     name = QLatin1String("#comment");
       
  5314 }
       
  5315 
       
  5316 QDomCommentPrivate::QDomCommentPrivate(QDomCommentPrivate* n, bool deep)
       
  5317     : QDomCharacterDataPrivate(n, deep)
       
  5318 {
       
  5319 }
       
  5320 
       
  5321 
       
  5322 QDomNodePrivate* QDomCommentPrivate::cloneNode(bool deep)
       
  5323 {
       
  5324     QDomNodePrivate* p = new QDomCommentPrivate(this, deep);
       
  5325     // We are not interested in this node
       
  5326     p->ref.deref();
       
  5327     return p;
       
  5328 }
       
  5329 
       
  5330 void QDomCommentPrivate::save(QTextStream& s, int depth, int indent) const
       
  5331 {
       
  5332     /* We don't output whitespace if we would pollute a text node. */
       
  5333     if (!(prev && prev->isText()))
       
  5334         s << QString(indent < 1 ? 0 : depth * indent, QLatin1Char(' '));
       
  5335 
       
  5336     s << "<!--" << value;
       
  5337     if (value.endsWith(QLatin1Char('-')))
       
  5338         s << ' '; // Ensures that XML comment doesn't end with --->
       
  5339     s << "-->";
       
  5340 
       
  5341     if (!(next && next->isText()))
       
  5342         s << endl;
       
  5343 }
       
  5344 
       
  5345 /**************************************************************
       
  5346  *
       
  5347  * QDomComment
       
  5348  *
       
  5349  **************************************************************/
       
  5350 
       
  5351 /*!
       
  5352     \class QDomComment
       
  5353     \reentrant
       
  5354     \brief The QDomComment class represents an XML comment.
       
  5355 
       
  5356     \inmodule QtXml
       
  5357     \ingroup xml-tools
       
  5358 
       
  5359     A comment in the parsed XML such as this:
       
  5360     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 15
       
  5361     is represented by QDomComment objects in the parsed Dom tree.
       
  5362 
       
  5363     For further information about the Document Object Model see
       
  5364     \l{http://www.w3.org/TR/REC-DOM-Level-1/} and
       
  5365     \l{http://www.w3.org/TR/DOM-Level-2-Core/}.
       
  5366     For a more general introduction of the DOM implementation see the
       
  5367     QDomDocument documentation.
       
  5368 */
       
  5369 
       
  5370 /*!
       
  5371     Constructs an empty comment. To construct a comment with content,
       
  5372     use the QDomDocument::createComment() function.
       
  5373 */
       
  5374 QDomComment::QDomComment()
       
  5375     : QDomCharacterData()
       
  5376 {
       
  5377 }
       
  5378 
       
  5379 /*!
       
  5380     Constructs a copy of \a x.
       
  5381 
       
  5382     The data of the copy is shared (shallow copy): modifying one node
       
  5383     will also change the other. If you want to make a deep copy, use
       
  5384     cloneNode().
       
  5385 */
       
  5386 QDomComment::QDomComment(const QDomComment& x)
       
  5387     : QDomCharacterData(x)
       
  5388 {
       
  5389 }
       
  5390 
       
  5391 QDomComment::QDomComment(QDomCommentPrivate* n)
       
  5392     : QDomCharacterData(n)
       
  5393 {
       
  5394 }
       
  5395 
       
  5396 /*!
       
  5397     Assigns \a x to this DOM comment.
       
  5398 
       
  5399     The data of the copy is shared (shallow copy): modifying one node
       
  5400     will also change the other. If you want to make a deep copy, use
       
  5401     cloneNode().
       
  5402 */
       
  5403 QDomComment& QDomComment::operator= (const QDomComment& x)
       
  5404 {
       
  5405     return (QDomComment&) QDomNode::operator=(x);
       
  5406 }
       
  5407 
       
  5408 /*!
       
  5409     \fn QDomNode::NodeType QDomComment::nodeType() const
       
  5410 
       
  5411     Returns \c CommentNode.
       
  5412 */
       
  5413 
       
  5414 /**************************************************************
       
  5415  *
       
  5416  * QDomCDATASectionPrivate
       
  5417  *
       
  5418  **************************************************************/
       
  5419 
       
  5420 QDomCDATASectionPrivate::QDomCDATASectionPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent,
       
  5421                                                     const QString& val)
       
  5422     : QDomTextPrivate(d, parent, val)
       
  5423 {
       
  5424     name = QLatin1String("#cdata-section");
       
  5425 }
       
  5426 
       
  5427 QDomCDATASectionPrivate::QDomCDATASectionPrivate(QDomCDATASectionPrivate* n, bool deep)
       
  5428     : QDomTextPrivate(n, deep)
       
  5429 {
       
  5430 }
       
  5431 
       
  5432 QDomNodePrivate* QDomCDATASectionPrivate::cloneNode(bool deep)
       
  5433 {
       
  5434     QDomNodePrivate* p = new QDomCDATASectionPrivate(this, deep);
       
  5435     // We are not interested in this node
       
  5436     p->ref.deref();
       
  5437     return p;
       
  5438 }
       
  5439 
       
  5440 void QDomCDATASectionPrivate::save(QTextStream& s, int, int) const
       
  5441 {
       
  5442     // ### How do we escape "]]>" ?
       
  5443     // "]]>" is not allowed; so there should be none in value anyway
       
  5444     s << "<![CDATA[" << value << "]]>";
       
  5445 }
       
  5446 
       
  5447 /**************************************************************
       
  5448  *
       
  5449  * QDomCDATASection
       
  5450  *
       
  5451  **************************************************************/
       
  5452 
       
  5453 /*!
       
  5454     \class QDomCDATASection
       
  5455     \reentrant
       
  5456     \brief The QDomCDATASection class represents an XML CDATA section.
       
  5457 
       
  5458     \inmodule QtXml
       
  5459     \ingroup xml-tools
       
  5460 
       
  5461     CDATA sections are used to escape blocks of text containing
       
  5462     characters that would otherwise be regarded as markup. The only
       
  5463     delimiter that is recognized in a CDATA section is the "]]&gt;"
       
  5464     string that terminates the CDATA section. CDATA sections cannot be
       
  5465     nested. Their primary purpose is for including material such as
       
  5466     XML fragments, without needing to escape all the delimiters.
       
  5467 
       
  5468     Adjacent QDomCDATASection nodes are not merged by the
       
  5469     QDomNode::normalize() function.
       
  5470 
       
  5471     For further information about the Document Object Model see
       
  5472     \l{http://www.w3.org/TR/REC-DOM-Level-1/} and
       
  5473     \l{http://www.w3.org/TR/DOM-Level-2-Core/}.
       
  5474     For a more general introduction of the DOM implementation see the
       
  5475     QDomDocument documentation.
       
  5476 */
       
  5477 
       
  5478 /*!
       
  5479     Constructs an empty CDATA section. To create a CDATA section with
       
  5480     content, use the QDomDocument::createCDATASection() function.
       
  5481 */
       
  5482 QDomCDATASection::QDomCDATASection()
       
  5483     : QDomText()
       
  5484 {
       
  5485 }
       
  5486 
       
  5487 /*!
       
  5488     Constructs a copy of \a x.
       
  5489 
       
  5490     The data of the copy is shared (shallow copy): modifying one node
       
  5491     will also change the other. If you want to make a deep copy, use
       
  5492     cloneNode().
       
  5493 */
       
  5494 QDomCDATASection::QDomCDATASection(const QDomCDATASection& x)
       
  5495     : QDomText(x)
       
  5496 {
       
  5497 }
       
  5498 
       
  5499 QDomCDATASection::QDomCDATASection(QDomCDATASectionPrivate* n)
       
  5500     : QDomText(n)
       
  5501 {
       
  5502 }
       
  5503 
       
  5504 /*!
       
  5505     Assigns \a x to this CDATA section.
       
  5506 
       
  5507     The data of the copy is shared (shallow copy): modifying one node
       
  5508     will also change the other. If you want to make a deep copy, use
       
  5509     cloneNode().
       
  5510 */
       
  5511 QDomCDATASection& QDomCDATASection::operator= (const QDomCDATASection& x)
       
  5512 {
       
  5513     return (QDomCDATASection&) QDomNode::operator=(x);
       
  5514 }
       
  5515 
       
  5516 /*!
       
  5517     \fn QDomNode::NodeType QDomCDATASection::nodeType() const
       
  5518 
       
  5519     Returns \c CDATASection.
       
  5520 */
       
  5521 
       
  5522 /**************************************************************
       
  5523  *
       
  5524  * QDomNotationPrivate
       
  5525  *
       
  5526  **************************************************************/
       
  5527 
       
  5528 QDomNotationPrivate::QDomNotationPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent,
       
  5529                                             const QString& aname,
       
  5530                                             const QString& pub, const QString& sys)
       
  5531     : QDomNodePrivate(d, parent)
       
  5532 {
       
  5533     name = aname;
       
  5534     m_pub = pub;
       
  5535     m_sys = sys;
       
  5536 }
       
  5537 
       
  5538 QDomNotationPrivate::QDomNotationPrivate(QDomNotationPrivate* n, bool deep)
       
  5539     : QDomNodePrivate(n, deep)
       
  5540 {
       
  5541     m_sys = n->m_sys;
       
  5542     m_pub = n->m_pub;
       
  5543 }
       
  5544 
       
  5545 QDomNodePrivate* QDomNotationPrivate::cloneNode(bool deep)
       
  5546 {
       
  5547     QDomNodePrivate* p = new QDomNotationPrivate(this, deep);
       
  5548     // We are not interested in this node
       
  5549     p->ref.deref();
       
  5550     return p;
       
  5551 }
       
  5552 
       
  5553 void QDomNotationPrivate::save(QTextStream& s, int, int) const
       
  5554 {
       
  5555     s << "<!NOTATION " << name << ' ';
       
  5556     if (!m_pub.isNull())  {
       
  5557         s << "PUBLIC " << quotedValue(m_pub);
       
  5558         if (!m_sys.isNull())
       
  5559             s << ' ' << quotedValue(m_sys);
       
  5560     }  else {
       
  5561         s << "SYSTEM " << quotedValue(m_sys);
       
  5562     }
       
  5563     s << '>' << endl;
       
  5564 }
       
  5565 
       
  5566 /**************************************************************
       
  5567  *
       
  5568  * QDomNotation
       
  5569  *
       
  5570  **************************************************************/
       
  5571 
       
  5572 #define IMPL ((QDomNotationPrivate*)impl)
       
  5573 
       
  5574 /*!
       
  5575     \class QDomNotation
       
  5576     \reentrant
       
  5577     \brief The QDomNotation class represents an XML notation.
       
  5578 
       
  5579     \inmodule QtXml
       
  5580     \ingroup xml-tools
       
  5581 
       
  5582     A notation either declares, by name, the format of an unparsed
       
  5583     entity (see section 4.7 of the XML 1.0 specification), or is used
       
  5584     for formal declaration of processing instruction targets (see
       
  5585     section 2.6 of the XML 1.0 specification).
       
  5586 
       
  5587     DOM does not support editing notation nodes; they are therefore
       
  5588     read-only.
       
  5589 
       
  5590     A notation node does not have any parent.
       
  5591 
       
  5592     You can retrieve the publicId() and systemId() from a notation
       
  5593     node.
       
  5594 
       
  5595     For further information about the Document Object Model see
       
  5596     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5597     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5598     For a more general introduction of the DOM implementation see the
       
  5599     QDomDocument documentation.
       
  5600 */
       
  5601 
       
  5602 
       
  5603 /*!
       
  5604     Constructor.
       
  5605 */
       
  5606 QDomNotation::QDomNotation()
       
  5607     : QDomNode()
       
  5608 {
       
  5609 }
       
  5610 
       
  5611 /*!
       
  5612     Constructs a copy of \a x.
       
  5613 
       
  5614     The data of the copy is shared (shallow copy): modifying one node
       
  5615     will also change the other. If you want to make a deep copy, use
       
  5616     cloneNode().
       
  5617 */
       
  5618 QDomNotation::QDomNotation(const QDomNotation& x)
       
  5619     : QDomNode(x)
       
  5620 {
       
  5621 }
       
  5622 
       
  5623 QDomNotation::QDomNotation(QDomNotationPrivate* n)
       
  5624     : QDomNode(n)
       
  5625 {
       
  5626 }
       
  5627 
       
  5628 /*!
       
  5629     Assigns \a x to this DOM notation.
       
  5630 
       
  5631     The data of the copy is shared (shallow copy): modifying one node
       
  5632     will also change the other. If you want to make a deep copy, use
       
  5633     cloneNode().
       
  5634 */
       
  5635 QDomNotation& QDomNotation::operator= (const QDomNotation& x)
       
  5636 {
       
  5637     return (QDomNotation&) QDomNode::operator=(x);
       
  5638 }
       
  5639 
       
  5640 /*!
       
  5641     \fn QDomNode::NodeType QDomNotation::nodeType() const
       
  5642 
       
  5643     Returns \c NotationNode.
       
  5644 */
       
  5645 
       
  5646 /*!
       
  5647     Returns the public identifier of this notation.
       
  5648 */
       
  5649 QString QDomNotation::publicId() const
       
  5650 {
       
  5651     if (!impl)
       
  5652         return QString();
       
  5653     return IMPL->m_pub;
       
  5654 }
       
  5655 
       
  5656 /*!
       
  5657     Returns the system identifier of this notation.
       
  5658 */
       
  5659 QString QDomNotation::systemId() const
       
  5660 {
       
  5661     if (!impl)
       
  5662         return QString();
       
  5663     return IMPL->m_sys;
       
  5664 }
       
  5665 
       
  5666 #undef IMPL
       
  5667 
       
  5668 /**************************************************************
       
  5669  *
       
  5670  * QDomEntityPrivate
       
  5671  *
       
  5672  **************************************************************/
       
  5673 
       
  5674 QDomEntityPrivate::QDomEntityPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent,
       
  5675                                         const QString& aname,
       
  5676                                         const QString& pub, const QString& sys, const QString& notation)
       
  5677     : QDomNodePrivate(d, parent)
       
  5678 {
       
  5679     name = aname;
       
  5680     m_pub = pub;
       
  5681     m_sys = sys;
       
  5682     m_notationName = notation;
       
  5683 }
       
  5684 
       
  5685 QDomEntityPrivate::QDomEntityPrivate(QDomEntityPrivate* n, bool deep)
       
  5686     : QDomNodePrivate(n, deep)
       
  5687 {
       
  5688     m_sys = n->m_sys;
       
  5689     m_pub = n->m_pub;
       
  5690     m_notationName = n->m_notationName;
       
  5691 }
       
  5692 
       
  5693 QDomNodePrivate* QDomEntityPrivate::cloneNode(bool deep)
       
  5694 {
       
  5695     QDomNodePrivate* p = new QDomEntityPrivate(this, deep);
       
  5696     // We are not interested in this node
       
  5697     p->ref.deref();
       
  5698     return p;
       
  5699 }
       
  5700 
       
  5701 /*
       
  5702   Encode an entity value upon saving.
       
  5703 */
       
  5704 static QByteArray encodeEntity(const QByteArray& str)
       
  5705 {
       
  5706     QByteArray tmp(str);
       
  5707     uint len = tmp.size();
       
  5708     uint i = 0;
       
  5709     const char* d = tmp.data();
       
  5710     while (i < len) {
       
  5711         if (d[i] == '%'){
       
  5712             tmp.replace(i, 1, "&#60;");
       
  5713             d = tmp;
       
  5714             len += 4;
       
  5715             i += 5;
       
  5716         }
       
  5717         else if (d[i] == '"') {
       
  5718             tmp.replace(i, 1, "&#34;");
       
  5719             d = tmp;
       
  5720             len += 4;
       
  5721             i += 5;
       
  5722         } else if (d[i] == '&' && i + 1 < len && d[i+1] == '#') {
       
  5723             // Dont encode &lt; or &quot; or &custom;.
       
  5724             // Only encode character references
       
  5725             tmp.replace(i, 1, "&#38;");
       
  5726             d = tmp;
       
  5727             len += 4;
       
  5728             i += 5;
       
  5729         } else {
       
  5730             ++i;
       
  5731         }
       
  5732     }
       
  5733 
       
  5734     return tmp;
       
  5735 }
       
  5736 
       
  5737 void QDomEntityPrivate::save(QTextStream& s, int, int) const
       
  5738 {
       
  5739     QString _name = name;
       
  5740     if (_name.startsWith(QLatin1Char('%')))
       
  5741         _name = QLatin1String("% ") + _name.mid(1);
       
  5742 
       
  5743     if (m_sys.isNull() && m_pub.isNull()) {
       
  5744         s << "<!ENTITY " << _name << " \"" << encodeEntity(value.toUtf8()) << "\">" << endl;
       
  5745     } else {
       
  5746         s << "<!ENTITY " << _name << ' ';
       
  5747         if (m_pub.isNull()) {
       
  5748             s << "SYSTEM " << quotedValue(m_sys);
       
  5749         } else {
       
  5750             s << "PUBLIC " << quotedValue(m_pub) << ' ' << quotedValue(m_sys);
       
  5751         }
       
  5752         if (! m_notationName.isNull()) {
       
  5753             s << " NDATA " << m_notationName;
       
  5754         }
       
  5755         s << '>' << endl;
       
  5756     }
       
  5757 }
       
  5758 
       
  5759 /**************************************************************
       
  5760  *
       
  5761  * QDomEntity
       
  5762  *
       
  5763  **************************************************************/
       
  5764 
       
  5765 #define IMPL ((QDomEntityPrivate*)impl)
       
  5766 
       
  5767 /*!
       
  5768     \class QDomEntity
       
  5769     \reentrant
       
  5770     \brief The QDomEntity class represents an XML entity.
       
  5771 
       
  5772     \inmodule QtXml
       
  5773     \ingroup xml-tools
       
  5774 
       
  5775     This class represents an entity in an XML document, either parsed
       
  5776     or unparsed. Note that this models the entity itself not the
       
  5777     entity declaration.
       
  5778 
       
  5779     DOM does not support editing entity nodes; if a user wants to make
       
  5780     changes to the contents of an entity, every related
       
  5781     QDomEntityReference node must be replaced in the DOM tree by a
       
  5782     clone of the entity's contents, and then the desired changes must
       
  5783     be made to each of the clones instead. All the descendants of an
       
  5784     entity node are read-only.
       
  5785 
       
  5786     An entity node does not have any parent.
       
  5787 
       
  5788     You can access the entity's publicId(), systemId() and
       
  5789     notationName() when available.
       
  5790 
       
  5791     For further information about the Document Object Model see
       
  5792     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5793     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5794     For a more general introduction of the DOM implementation see the
       
  5795     QDomDocument documentation.
       
  5796 */
       
  5797 
       
  5798 
       
  5799 /*!
       
  5800     Constructs an empty entity.
       
  5801 */
       
  5802 QDomEntity::QDomEntity()
       
  5803     : QDomNode()
       
  5804 {
       
  5805 }
       
  5806 
       
  5807 
       
  5808 /*!
       
  5809     Constructs a copy of \a x.
       
  5810 
       
  5811     The data of the copy is shared (shallow copy): modifying one node
       
  5812     will also change the other. If you want to make a deep copy, use
       
  5813     cloneNode().
       
  5814 */
       
  5815 QDomEntity::QDomEntity(const QDomEntity& x)
       
  5816     : QDomNode(x)
       
  5817 {
       
  5818 }
       
  5819 
       
  5820 QDomEntity::QDomEntity(QDomEntityPrivate* n)
       
  5821     : QDomNode(n)
       
  5822 {
       
  5823 }
       
  5824 
       
  5825 /*!
       
  5826     Assigns \a x to this DOM entity.
       
  5827 
       
  5828     The data of the copy is shared (shallow copy): modifying one node
       
  5829     will also change the other. If you want to make a deep copy, use
       
  5830     cloneNode().
       
  5831 */
       
  5832 QDomEntity& QDomEntity::operator= (const QDomEntity& x)
       
  5833 {
       
  5834     return (QDomEntity&) QDomNode::operator=(x);
       
  5835 }
       
  5836 
       
  5837 /*!
       
  5838     \fn QDomNode::NodeType QDomEntity::nodeType() const
       
  5839 
       
  5840     Returns \c EntityNode.
       
  5841 */
       
  5842 
       
  5843 /*!
       
  5844     Returns the public identifier associated with this entity. If the
       
  5845     public identifier was not specified an empty string is returned.
       
  5846 */
       
  5847 QString QDomEntity::publicId() const
       
  5848 {
       
  5849     if (!impl)
       
  5850         return QString();
       
  5851     return IMPL->m_pub;
       
  5852 }
       
  5853 
       
  5854 /*!
       
  5855     Returns the system identifier associated with this entity. If the
       
  5856     system identifier was not specified an empty string is returned.
       
  5857 */
       
  5858 QString QDomEntity::systemId() const
       
  5859 {
       
  5860     if (!impl)
       
  5861         return QString();
       
  5862     return IMPL->m_sys;
       
  5863 }
       
  5864 
       
  5865 /*!
       
  5866     For unparsed entities this function returns the name of the
       
  5867     notation for the entity. For parsed entities this function returns
       
  5868     an empty string.
       
  5869 */
       
  5870 QString QDomEntity::notationName() const
       
  5871 {
       
  5872     if (!impl)
       
  5873         return QString();
       
  5874     return IMPL->m_notationName;
       
  5875 }
       
  5876 
       
  5877 #undef IMPL
       
  5878 
       
  5879 /**************************************************************
       
  5880  *
       
  5881  * QDomEntityReferencePrivate
       
  5882  *
       
  5883  **************************************************************/
       
  5884 
       
  5885 QDomEntityReferencePrivate::QDomEntityReferencePrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& aname)
       
  5886     : QDomNodePrivate(d, parent)
       
  5887 {
       
  5888     name = aname;
       
  5889 }
       
  5890 
       
  5891 QDomEntityReferencePrivate::QDomEntityReferencePrivate(QDomNodePrivate* n, bool deep)
       
  5892     : QDomNodePrivate(n, deep)
       
  5893 {
       
  5894 }
       
  5895 
       
  5896 QDomNodePrivate* QDomEntityReferencePrivate::cloneNode(bool deep)
       
  5897 {
       
  5898     QDomNodePrivate* p = new QDomEntityReferencePrivate(this, deep);
       
  5899     // We are not interested in this node
       
  5900     p->ref.deref();
       
  5901     return p;
       
  5902 }
       
  5903 
       
  5904 void QDomEntityReferencePrivate::save(QTextStream& s, int, int) const
       
  5905 {
       
  5906     s << '&' << name << ';';
       
  5907 }
       
  5908 
       
  5909 /**************************************************************
       
  5910  *
       
  5911  * QDomEntityReference
       
  5912  *
       
  5913  **************************************************************/
       
  5914 
       
  5915 /*!
       
  5916     \class QDomEntityReference
       
  5917     \reentrant
       
  5918     \brief The QDomEntityReference class represents an XML entity reference.
       
  5919 
       
  5920     \inmodule QtXml
       
  5921     \ingroup xml-tools
       
  5922 
       
  5923     A QDomEntityReference object may be inserted into the DOM tree
       
  5924     when an entity reference is in the source document, or when the
       
  5925     user wishes to insert an entity reference.
       
  5926 
       
  5927     Note that character references and references to predefined
       
  5928     entities are expanded by the XML processor so that characters are
       
  5929     represented by their Unicode equivalent rather than by an entity
       
  5930     reference.
       
  5931 
       
  5932     Moreover, the XML processor may completely expand references to
       
  5933     entities while building the DOM tree, instead of providing
       
  5934     QDomEntityReference objects.
       
  5935 
       
  5936     If it does provide such objects, then for a given entity reference
       
  5937     node, it may be that there is no entity node representing the
       
  5938     referenced entity; but if such an entity exists, then the child
       
  5939     list of the entity reference node is the same as that of the
       
  5940     entity  node. As with the entity node, all descendants of the
       
  5941     entity reference are read-only.
       
  5942 
       
  5943     For further information about the Document Object Model see
       
  5944     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5945     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5946     For a more general introduction of the DOM implementation see the
       
  5947     QDomDocument documentation.
       
  5948 */
       
  5949 
       
  5950 /*!
       
  5951     Constructs an empty entity reference. Use
       
  5952     QDomDocument::createEntityReference() to create a entity reference
       
  5953     with content.
       
  5954 */
       
  5955 QDomEntityReference::QDomEntityReference()
       
  5956     : QDomNode()
       
  5957 {
       
  5958 }
       
  5959 
       
  5960 /*!
       
  5961     Constructs a copy of \a x.
       
  5962 
       
  5963     The data of the copy is shared (shallow copy): modifying one node
       
  5964     will also change the other. If you want to make a deep copy, use
       
  5965     cloneNode().
       
  5966 */
       
  5967 QDomEntityReference::QDomEntityReference(const QDomEntityReference& x)
       
  5968     : QDomNode(x)
       
  5969 {
       
  5970 }
       
  5971 
       
  5972 QDomEntityReference::QDomEntityReference(QDomEntityReferencePrivate* n)
       
  5973     : QDomNode(n)
       
  5974 {
       
  5975 }
       
  5976 
       
  5977 /*!
       
  5978     Assigns \a x to this entity reference.
       
  5979 
       
  5980     The data of the copy is shared (shallow copy): modifying one node
       
  5981     will also change the other. If you want to make a deep copy, use
       
  5982     cloneNode().
       
  5983 */
       
  5984 QDomEntityReference& QDomEntityReference::operator= (const QDomEntityReference& x)
       
  5985 {
       
  5986     return (QDomEntityReference&) QDomNode::operator=(x);
       
  5987 }
       
  5988 
       
  5989 /*!
       
  5990     \fn QDomNode::NodeType QDomEntityReference::nodeType() const
       
  5991 
       
  5992     Returns \c EntityReference.
       
  5993 */
       
  5994 
       
  5995 /**************************************************************
       
  5996  *
       
  5997  * QDomProcessingInstructionPrivate
       
  5998  *
       
  5999  **************************************************************/
       
  6000 
       
  6001 QDomProcessingInstructionPrivate::QDomProcessingInstructionPrivate(QDomDocumentPrivate* d,
       
  6002         QDomNodePrivate* parent, const QString& target, const QString& data)
       
  6003     : QDomNodePrivate(d, parent)
       
  6004 {
       
  6005     name = target;
       
  6006     value = data;
       
  6007 }
       
  6008 
       
  6009 QDomProcessingInstructionPrivate::QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate* n, bool deep)
       
  6010     : QDomNodePrivate(n, deep)
       
  6011 {
       
  6012 }
       
  6013 
       
  6014 
       
  6015 QDomNodePrivate* QDomProcessingInstructionPrivate::cloneNode(bool deep)
       
  6016 {
       
  6017     QDomNodePrivate* p = new QDomProcessingInstructionPrivate(this, deep);
       
  6018     // We are not interested in this node
       
  6019     p->ref.deref();
       
  6020     return p;
       
  6021 }
       
  6022 
       
  6023 void QDomProcessingInstructionPrivate::save(QTextStream& s, int, int) const
       
  6024 {
       
  6025     s << "<?" << name << ' ' << value << "?>" << endl;
       
  6026 }
       
  6027 
       
  6028 /**************************************************************
       
  6029  *
       
  6030  * QDomProcessingInstruction
       
  6031  *
       
  6032  **************************************************************/
       
  6033 
       
  6034 /*!
       
  6035     \class QDomProcessingInstruction
       
  6036     \reentrant
       
  6037     \brief The QDomProcessingInstruction class represents an XML processing
       
  6038     instruction.
       
  6039 
       
  6040     \inmodule QtXml
       
  6041     \ingroup xml-tools
       
  6042 
       
  6043     Processing instructions are used in XML to keep processor-specific
       
  6044     information in the text of the document.
       
  6045 
       
  6046     The XML declaration that appears at the top of an XML document,
       
  6047     typically \tt{<?xml version='1.0' encoding='UTF-8'?>}, is treated by QDom as a
       
  6048     processing instruction. This is unfortunate, since the XML declaration is
       
  6049     not a processing instruction; among other differences, it cannot be
       
  6050     inserted into a document anywhere but on the first line.
       
  6051 
       
  6052     Do not use this function to create an xml declaration, since although it
       
  6053     has the same syntax as a processing instruction, it isn't, and might not
       
  6054     be treated by QDom as such.
       
  6055 
       
  6056     The content of the processing instruction is retrieved with data()
       
  6057     and set with setData(). The processing instruction's target is
       
  6058     retrieved with target().
       
  6059 
       
  6060     For further information about the Document Object Model see
       
  6061     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  6062     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  6063     For a more general introduction of the DOM implementation see the
       
  6064     QDomDocument documentation.
       
  6065 */
       
  6066 
       
  6067 /*!
       
  6068     Constructs an empty processing instruction. Use
       
  6069     QDomDocument::createProcessingInstruction() to create a processing
       
  6070     instruction with content.
       
  6071 */
       
  6072 QDomProcessingInstruction::QDomProcessingInstruction()
       
  6073     : QDomNode()
       
  6074 {
       
  6075 }
       
  6076 
       
  6077 /*!
       
  6078     Constructs a copy of \a x.
       
  6079 
       
  6080     The data of the copy is shared (shallow copy): modifying one node
       
  6081     will also change the other. If you want to make a deep copy, use
       
  6082     cloneNode().
       
  6083 */
       
  6084 QDomProcessingInstruction::QDomProcessingInstruction(const QDomProcessingInstruction& x)
       
  6085     : QDomNode(x)
       
  6086 {
       
  6087 }
       
  6088 
       
  6089 QDomProcessingInstruction::QDomProcessingInstruction(QDomProcessingInstructionPrivate* n)
       
  6090     : QDomNode(n)
       
  6091 {
       
  6092 }
       
  6093 
       
  6094 /*!
       
  6095     Assigns \a x to this processing instruction.
       
  6096 
       
  6097     The data of the copy is shared (shallow copy): modifying one node
       
  6098     will also change the other. If you want to make a deep copy, use
       
  6099     cloneNode().
       
  6100 */
       
  6101 QDomProcessingInstruction& QDomProcessingInstruction::operator= (const QDomProcessingInstruction& x)
       
  6102 {
       
  6103     return (QDomProcessingInstruction&) QDomNode::operator=(x);
       
  6104 }
       
  6105 
       
  6106 /*!
       
  6107     \fn QDomNode::NodeType QDomProcessingInstruction::nodeType() const
       
  6108 
       
  6109     Returns \c ProcessingInstructionNode.
       
  6110 */
       
  6111 
       
  6112 /*!
       
  6113     Returns the target of this processing instruction.
       
  6114 
       
  6115     \sa data()
       
  6116 */
       
  6117 QString QDomProcessingInstruction::target() const
       
  6118 {
       
  6119     if (!impl)
       
  6120         return QString();
       
  6121     return impl->nodeName();
       
  6122 }
       
  6123 
       
  6124 /*!
       
  6125     Returns the content of this processing instruction.
       
  6126 
       
  6127     \sa setData() target()
       
  6128 */
       
  6129 QString QDomProcessingInstruction::data() const
       
  6130 {
       
  6131     if (!impl)
       
  6132         return QString();
       
  6133     return impl->nodeValue();
       
  6134 }
       
  6135 
       
  6136 /*!
       
  6137     Sets the data contained in the processing instruction to \a d.
       
  6138 
       
  6139     \sa data()
       
  6140 */
       
  6141 void QDomProcessingInstruction::setData(const QString& d)
       
  6142 {
       
  6143     if (!impl)
       
  6144         return;
       
  6145     impl->setNodeValue(d);
       
  6146 }
       
  6147 
       
  6148 /**************************************************************
       
  6149  *
       
  6150  * QDomDocumentPrivate
       
  6151  *
       
  6152  **************************************************************/
       
  6153 
       
  6154 QDomDocumentPrivate::QDomDocumentPrivate()
       
  6155     : QDomNodePrivate(0),
       
  6156       impl(new QDomImplementationPrivate),
       
  6157       nodeListTime(1)
       
  6158 {
       
  6159     type = new QDomDocumentTypePrivate(this, this);
       
  6160     type->ref.deref();
       
  6161 
       
  6162     name = QLatin1String("#document");
       
  6163 }
       
  6164 
       
  6165 QDomDocumentPrivate::QDomDocumentPrivate(const QString& aname)
       
  6166     : QDomNodePrivate(0),
       
  6167       impl(new QDomImplementationPrivate),
       
  6168       nodeListTime(1)
       
  6169 {
       
  6170     type = new QDomDocumentTypePrivate(this, this);
       
  6171     type->ref.deref();
       
  6172     type->name = aname;
       
  6173 
       
  6174     name = QLatin1String("#document");
       
  6175 }
       
  6176 
       
  6177 QDomDocumentPrivate::QDomDocumentPrivate(QDomDocumentTypePrivate* dt)
       
  6178     : QDomNodePrivate(0),
       
  6179       impl(new QDomImplementationPrivate),
       
  6180       nodeListTime(1)
       
  6181 {
       
  6182     if (dt != 0) {
       
  6183         type = dt;
       
  6184     } else {
       
  6185         type = new QDomDocumentTypePrivate(this, this);
       
  6186         type->ref.deref();
       
  6187     }
       
  6188 
       
  6189     name = QLatin1String("#document");
       
  6190 }
       
  6191 
       
  6192 QDomDocumentPrivate::QDomDocumentPrivate(QDomDocumentPrivate* n, bool deep)
       
  6193     : QDomNodePrivate(n, deep),
       
  6194       impl(n->impl->clone()),
       
  6195       nodeListTime(1)
       
  6196 {
       
  6197     type = static_cast<QDomDocumentTypePrivate*>(n->type->cloneNode());
       
  6198     type->setParent(this);
       
  6199 }
       
  6200 
       
  6201 QDomDocumentPrivate::~QDomDocumentPrivate()
       
  6202 {
       
  6203 }
       
  6204 
       
  6205 void QDomDocumentPrivate::clear()
       
  6206 {
       
  6207     impl.reset();
       
  6208     type.reset();
       
  6209     QDomNodePrivate::clear();
       
  6210 }
       
  6211 
       
  6212 static void initializeReader(QXmlSimpleReader &reader, bool namespaceProcessing)
       
  6213 {
       
  6214     reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), namespaceProcessing);
       
  6215     reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), !namespaceProcessing);
       
  6216     reader.setFeature(QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData"), false); // Shouldn't change in Qt 4
       
  6217 }
       
  6218 
       
  6219 bool QDomDocumentPrivate::setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6220 {
       
  6221     QXmlSimpleReader reader;
       
  6222     initializeReader(reader, namespaceProcessing);
       
  6223     return setContent(source, &reader, errorMsg, errorLine, errorColumn);
       
  6224 }
       
  6225 
       
  6226 bool QDomDocumentPrivate::setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6227 {
       
  6228     clear();
       
  6229     impl = new QDomImplementationPrivate;
       
  6230     type = new QDomDocumentTypePrivate(this, this);
       
  6231     type->ref.deref();
       
  6232 
       
  6233     bool namespaceProcessing = reader->feature(QLatin1String("http://xml.org/sax/features/namespaces"))
       
  6234         && !reader->feature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"));
       
  6235 
       
  6236     QDomHandler hnd(this, namespaceProcessing);
       
  6237     reader->setContentHandler(&hnd);
       
  6238     reader->setErrorHandler(&hnd);
       
  6239     reader->setLexicalHandler(&hnd);
       
  6240     reader->setDeclHandler(&hnd);
       
  6241     reader->setDTDHandler(&hnd);
       
  6242 
       
  6243     if (!reader->parse(source)) {
       
  6244         if (errorMsg)
       
  6245             *errorMsg = hnd.errorMsg;
       
  6246         if (errorLine)
       
  6247             *errorLine = hnd.errorLine;
       
  6248         if (errorColumn)
       
  6249             *errorColumn = hnd.errorColumn;
       
  6250         return false;
       
  6251     }
       
  6252 
       
  6253     return true;
       
  6254 }
       
  6255 
       
  6256 QDomNodePrivate* QDomDocumentPrivate::cloneNode(bool deep)
       
  6257 {
       
  6258     QDomNodePrivate *p = new QDomDocumentPrivate(this, deep);
       
  6259     // We are not interested in this node
       
  6260     p->ref.deref();
       
  6261     return p;
       
  6262 }
       
  6263 
       
  6264 QDomElementPrivate* QDomDocumentPrivate::documentElement()
       
  6265 {
       
  6266     QDomNodePrivate *p = first;
       
  6267     while (p && !p->isElement())
       
  6268         p = p->next;
       
  6269 
       
  6270     return static_cast<QDomElementPrivate *>(p);
       
  6271 }
       
  6272 
       
  6273 QDomElementPrivate* QDomDocumentPrivate::createElement(const QString &tagName)
       
  6274 {
       
  6275     bool ok;
       
  6276     QString fixedName = fixedXmlName(tagName, &ok);
       
  6277     if (!ok)
       
  6278         return 0;
       
  6279 
       
  6280     QDomElementPrivate *e = new QDomElementPrivate(this, 0, fixedName);
       
  6281     e->ref.deref();
       
  6282     return e;
       
  6283 }
       
  6284 
       
  6285 QDomElementPrivate* QDomDocumentPrivate::createElementNS(const QString &nsURI, const QString &qName)
       
  6286 {
       
  6287     bool ok;
       
  6288     QString fixedName = fixedXmlName(qName, &ok, true);
       
  6289     if (!ok)
       
  6290         return 0;
       
  6291 
       
  6292     QDomElementPrivate *e = new QDomElementPrivate(this, 0, nsURI, fixedName);
       
  6293     e->ref.deref();
       
  6294     return e;
       
  6295 }
       
  6296 
       
  6297 QDomDocumentFragmentPrivate* QDomDocumentPrivate::createDocumentFragment()
       
  6298 {
       
  6299     QDomDocumentFragmentPrivate *f = new QDomDocumentFragmentPrivate(this, (QDomNodePrivate*)0);
       
  6300     f->ref.deref();
       
  6301     return f;
       
  6302 }
       
  6303 
       
  6304 QDomTextPrivate* QDomDocumentPrivate::createTextNode(const QString &data)
       
  6305 {
       
  6306     bool ok;
       
  6307     QString fixedData = fixedCharData(data, &ok);
       
  6308     if (!ok)
       
  6309         return 0;
       
  6310 
       
  6311     QDomTextPrivate *t = new QDomTextPrivate(this, 0, fixedData);
       
  6312     t->ref.deref();
       
  6313     return t;
       
  6314 }
       
  6315 
       
  6316 QDomCommentPrivate* QDomDocumentPrivate::createComment(const QString &data)
       
  6317 {
       
  6318     bool ok;
       
  6319     QString fixedData = fixedComment(data, &ok);
       
  6320     if (!ok)
       
  6321         return 0;
       
  6322 
       
  6323     QDomCommentPrivate *c = new QDomCommentPrivate(this, 0, fixedData);
       
  6324     c->ref.deref();
       
  6325     return c;
       
  6326 }
       
  6327 
       
  6328 QDomCDATASectionPrivate* QDomDocumentPrivate::createCDATASection(const QString &data)
       
  6329 {
       
  6330     bool ok;
       
  6331     QString fixedData = fixedCDataSection(data, &ok);
       
  6332     if (!ok)
       
  6333         return 0;
       
  6334 
       
  6335     QDomCDATASectionPrivate *c = new QDomCDATASectionPrivate(this, 0, fixedData);
       
  6336     c->ref.deref();
       
  6337     return c;
       
  6338 }
       
  6339 
       
  6340 QDomProcessingInstructionPrivate* QDomDocumentPrivate::createProcessingInstruction(const QString &target,
       
  6341                                                                                    const QString &data)
       
  6342 {
       
  6343     bool ok;
       
  6344     QString fixedData = fixedPIData(data, &ok);
       
  6345     if (!ok)
       
  6346         return 0;
       
  6347     // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
       
  6348     QString fixedTarget = fixedXmlName(target, &ok);
       
  6349     if (!ok)
       
  6350         return 0;
       
  6351 
       
  6352     QDomProcessingInstructionPrivate *p = new QDomProcessingInstructionPrivate(this, 0, fixedTarget, fixedData);
       
  6353     p->ref.deref();
       
  6354     return p;
       
  6355 }
       
  6356 QDomAttrPrivate* QDomDocumentPrivate::createAttribute(const QString &aname)
       
  6357 {
       
  6358     bool ok;
       
  6359     QString fixedName = fixedXmlName(aname, &ok);
       
  6360     if (!ok)
       
  6361         return 0;
       
  6362 
       
  6363     QDomAttrPrivate *a = new QDomAttrPrivate(this, 0, fixedName);
       
  6364     a->ref.deref();
       
  6365     return a;
       
  6366 }
       
  6367 
       
  6368 QDomAttrPrivate* QDomDocumentPrivate::createAttributeNS(const QString &nsURI, const QString &qName)
       
  6369 {
       
  6370     bool ok;
       
  6371     QString fixedName = fixedXmlName(qName, &ok, true);
       
  6372     if (!ok)
       
  6373         return 0;
       
  6374 
       
  6375     QDomAttrPrivate *a = new QDomAttrPrivate(this, 0, nsURI, fixedName);
       
  6376     a->ref.deref();
       
  6377     return a;
       
  6378 }
       
  6379 
       
  6380 QDomEntityReferencePrivate* QDomDocumentPrivate::createEntityReference(const QString &aname)
       
  6381 {
       
  6382     bool ok;
       
  6383     QString fixedName = fixedXmlName(aname, &ok);
       
  6384     if (!ok)
       
  6385         return 0;
       
  6386 
       
  6387     QDomEntityReferencePrivate *e = new QDomEntityReferencePrivate(this, 0, fixedName);
       
  6388     e->ref.deref();
       
  6389     return e;
       
  6390 }
       
  6391 
       
  6392 QDomNodePrivate* QDomDocumentPrivate::importNode(const QDomNodePrivate *importedNode, bool deep)
       
  6393 {
       
  6394     QDomNodePrivate *node = 0;
       
  6395     switch (importedNode->nodeType()) {
       
  6396         case QDomNode::AttributeNode:
       
  6397             node = new QDomAttrPrivate((QDomAttrPrivate*)importedNode, true);
       
  6398             break;
       
  6399         case QDomNode::DocumentFragmentNode:
       
  6400             node = new QDomDocumentFragmentPrivate((QDomDocumentFragmentPrivate*)importedNode, deep);
       
  6401             break;
       
  6402         case QDomNode::ElementNode:
       
  6403             node = new QDomElementPrivate((QDomElementPrivate*)importedNode, deep);
       
  6404             break;
       
  6405         case QDomNode::EntityNode:
       
  6406             node = new QDomEntityPrivate((QDomEntityPrivate*)importedNode, deep);
       
  6407             break;
       
  6408         case QDomNode::EntityReferenceNode:
       
  6409             node = new QDomEntityReferencePrivate((QDomEntityReferencePrivate*)importedNode, false);
       
  6410             break;
       
  6411         case QDomNode::NotationNode:
       
  6412             node = new QDomNotationPrivate((QDomNotationPrivate*)importedNode, deep);
       
  6413             break;
       
  6414         case QDomNode::ProcessingInstructionNode:
       
  6415             node = new QDomProcessingInstructionPrivate((QDomProcessingInstructionPrivate*)importedNode, deep);
       
  6416             break;
       
  6417         case QDomNode::TextNode:
       
  6418             node = new QDomTextPrivate((QDomTextPrivate*)importedNode, deep);
       
  6419             break;
       
  6420         case QDomNode::CDATASectionNode:
       
  6421             node = new QDomCDATASectionPrivate((QDomCDATASectionPrivate*)importedNode, deep);
       
  6422             break;
       
  6423         case QDomNode::CommentNode:
       
  6424             node = new QDomCommentPrivate((QDomCommentPrivate*)importedNode, deep);
       
  6425             break;
       
  6426         default:
       
  6427             break;
       
  6428     }
       
  6429     if (node) {
       
  6430         node->setOwnerDocument(this);
       
  6431         // The QDomNode constructor increases the refcount, so deref first to
       
  6432         // keep refcount balanced.
       
  6433         node->ref.deref();
       
  6434     }
       
  6435     return node;
       
  6436 }
       
  6437 
       
  6438 void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNode::EncodingPolicy encUsed) const
       
  6439 {
       
  6440     const QDomNodePrivate* n = first;
       
  6441 
       
  6442     if(encUsed == QDomNode::EncodingFromDocument) {
       
  6443 #ifndef QT_NO_TEXTCODEC
       
  6444         const QDomNodePrivate* n = first;
       
  6445 
       
  6446         QTextCodec *codec = 0;
       
  6447 
       
  6448         if (n && n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml")) {
       
  6449             // we have an XML declaration
       
  6450             QString data = n->nodeValue();
       
  6451             QRegExp encoding(QString::fromLatin1("encoding\\s*=\\s*((\"([^\"]*)\")|('([^']*)'))"));
       
  6452             encoding.indexIn(data);
       
  6453             QString enc = encoding.cap(3);
       
  6454             if (enc.isEmpty())
       
  6455                 enc = encoding.cap(5);
       
  6456             if (!enc.isEmpty())
       
  6457                 codec = QTextCodec::codecForName(enc.toLatin1().data());
       
  6458         }
       
  6459         if (!codec)
       
  6460             codec = QTextCodec::codecForName("UTF-8");
       
  6461         if (codec)
       
  6462             s.setCodec(codec);
       
  6463 #endif
       
  6464         bool doc = false;
       
  6465 
       
  6466         while (n) {
       
  6467             if (!doc && !(n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml"))) {
       
  6468                 // save doctype after XML declaration
       
  6469                 type->save(s, 0, indent);
       
  6470                 doc = true;
       
  6471             }
       
  6472             n->save(s, 0, indent);
       
  6473             n = n->next;
       
  6474         }
       
  6475     }
       
  6476     else {
       
  6477 
       
  6478         // Write out the XML declaration.
       
  6479 #ifdef QT_NO_TEXTCODEC
       
  6480         const QLatin1String codecName("iso-8859-1");
       
  6481 #else
       
  6482         const QTextCodec *const codec = s.codec();
       
  6483         Q_ASSERT_X(codec, "QDomNode::save()", "A codec must be specified in the text stream.");
       
  6484         const QByteArray codecName = codec->name();
       
  6485 #endif
       
  6486 
       
  6487         s << "<?xml version=\"1.0\" encoding=\""
       
  6488           << codecName
       
  6489           << "\"?>\n";
       
  6490 
       
  6491         //  Skip the first processing instruction by name "xml", if any such exists.
       
  6492         const QDomNodePrivate* startNode = n;
       
  6493 
       
  6494         // First, we try to find the PI and sets the startNode to the one appearing after it.
       
  6495         while (n) {
       
  6496             if(n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml")) {
       
  6497                 startNode = n->next;
       
  6498                 break;
       
  6499             }
       
  6500             else
       
  6501                 n = n->next;
       
  6502         }
       
  6503 
       
  6504         // Now we serialize all the nodes after the faked XML declaration(the PI).
       
  6505         while(startNode) {
       
  6506             startNode->save(s, 0, indent);
       
  6507             startNode = startNode->next;
       
  6508         }
       
  6509     }
       
  6510 }
       
  6511 
       
  6512 /**************************************************************
       
  6513  *
       
  6514  * QDomDocument
       
  6515  *
       
  6516  **************************************************************/
       
  6517 
       
  6518 #define IMPL ((QDomDocumentPrivate*)impl)
       
  6519 
       
  6520 /*!
       
  6521     \class QDomDocument
       
  6522     \reentrant
       
  6523     \brief The QDomDocument class represents an XML document.
       
  6524 
       
  6525     \inmodule QtXml
       
  6526 
       
  6527     \ingroup xml-tools
       
  6528 
       
  6529     The QDomDocument class represents the entire XML document.
       
  6530     Conceptually, it is the root of the document tree, and provides
       
  6531     the primary access to the document's data.
       
  6532 
       
  6533     Since elements, text nodes, comments, processing instructions,
       
  6534     etc., cannot exist outside the context of a document, the document
       
  6535     class also contains the factory functions needed to create these
       
  6536     objects. The node objects created have an ownerDocument() function
       
  6537     which associates them with the document within whose context they
       
  6538     were created. The DOM classes that will be used most often are
       
  6539     QDomNode, QDomDocument, QDomElement and QDomText.
       
  6540 
       
  6541     The parsed XML is represented internally by a tree of objects that
       
  6542     can be accessed using the various QDom classes. All QDom classes
       
  6543     only \e reference objects in the internal tree. The internal
       
  6544     objects in the DOM tree will get deleted once the last QDom
       
  6545     object referencing them and the QDomDocument itself are deleted.
       
  6546 
       
  6547     Creation of elements, text nodes, etc. is done using the various
       
  6548     factory functions provided in this class. Using the default
       
  6549     constructors of the QDom classes will only result in empty
       
  6550     objects that cannot be manipulated or inserted into the Document.
       
  6551 
       
  6552     The QDomDocument class has several functions for creating document
       
  6553     data, for example, createElement(), createTextNode(),
       
  6554     createComment(), createCDATASection(),
       
  6555     createProcessingInstruction(), createAttribute() and
       
  6556     createEntityReference(). Some of these functions have versions
       
  6557     that support namespaces, i.e. createElementNS() and
       
  6558     createAttributeNS(). The createDocumentFragment() function is used
       
  6559     to hold parts of the document; this is useful for manipulating for
       
  6560     complex documents.
       
  6561 
       
  6562     The entire content of the document is set with setContent(). This
       
  6563     function parses the string it is passed as an XML document and
       
  6564     creates the DOM tree that represents the document. The root
       
  6565     element is available using documentElement(). The textual
       
  6566     representation of the document can be obtained using toString().
       
  6567 
       
  6568     It is possible to insert a node from another document into the
       
  6569     document using importNode().
       
  6570 
       
  6571     You can obtain a list of all the elements that have a particular
       
  6572     tag with elementsByTagName() or with elementsByTagNameNS().
       
  6573 
       
  6574     The QDom classes are typically used as follows:
       
  6575     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 16
       
  6576 
       
  6577     Once \c doc and \c elem go out of scope, the whole internal tree
       
  6578     representing the XML document is deleted.
       
  6579 
       
  6580     To create a document using DOM use code like this:
       
  6581     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 17
       
  6582 
       
  6583     For further information about the Document Object Model see
       
  6584     the Document Object Model (DOM)
       
  6585     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  6586     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}
       
  6587     Specifications.
       
  6588 
       
  6589     \sa {DOM Bookmarks Example}, {Simple DOM Model Example}
       
  6590 */
       
  6591 
       
  6592 
       
  6593 /*!
       
  6594     Constructs an empty document.
       
  6595 */
       
  6596 QDomDocument::QDomDocument()
       
  6597 {
       
  6598     impl = 0;
       
  6599 }
       
  6600 
       
  6601 /*!
       
  6602     Creates a document and sets the name of the document type to \a
       
  6603     name.
       
  6604 */
       
  6605 QDomDocument::QDomDocument(const QString& name)
       
  6606 {
       
  6607     // We take over ownership
       
  6608     impl = new QDomDocumentPrivate(name);
       
  6609 }
       
  6610 
       
  6611 /*!
       
  6612     Creates a document with the document type \a doctype.
       
  6613 
       
  6614     \sa QDomImplementation::createDocumentType()
       
  6615 */
       
  6616 QDomDocument::QDomDocument(const QDomDocumentType& doctype)
       
  6617 {
       
  6618     impl = new QDomDocumentPrivate((QDomDocumentTypePrivate*)(doctype.impl));
       
  6619 }
       
  6620 
       
  6621 /*!
       
  6622     Constructs a copy of \a x.
       
  6623 
       
  6624     The data of the copy is shared (shallow copy): modifying one node
       
  6625     will also change the other. If you want to make a deep copy, use
       
  6626     cloneNode().
       
  6627 */
       
  6628 QDomDocument::QDomDocument(const QDomDocument& x)
       
  6629     : QDomNode(x)
       
  6630 {
       
  6631 }
       
  6632 
       
  6633 QDomDocument::QDomDocument(QDomDocumentPrivate* x)
       
  6634     : QDomNode(x)
       
  6635 {
       
  6636 }
       
  6637 
       
  6638 /*!
       
  6639     Assigns \a x to this DOM document.
       
  6640 
       
  6641     The data of the copy is shared (shallow copy): modifying one node
       
  6642     will also change the other. If you want to make a deep copy, use
       
  6643     cloneNode().
       
  6644 */
       
  6645 QDomDocument& QDomDocument::operator= (const QDomDocument& x)
       
  6646 {
       
  6647     return (QDomDocument&) QDomNode::operator=(x);
       
  6648 }
       
  6649 
       
  6650 /*!
       
  6651     Destroys the object and frees its resources.
       
  6652 */
       
  6653 QDomDocument::~QDomDocument()
       
  6654 {
       
  6655 }
       
  6656 
       
  6657 /*!
       
  6658     \overload
       
  6659 
       
  6660     This function reads the XML document from the string \a text, returning
       
  6661     true if the content was successfully parsed; otherwise returns false.
       
  6662     Since \a text is already a Unicode string, no encoding detection
       
  6663     is done.
       
  6664 */
       
  6665 bool QDomDocument::setContent(const QString& text, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6666 {
       
  6667     if (!impl)
       
  6668         impl = new QDomDocumentPrivate();
       
  6669     QXmlInputSource source;
       
  6670     source.setData(text);
       
  6671     return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn);
       
  6672 }
       
  6673 
       
  6674 /*!
       
  6675     \nonreentrant
       
  6676 
       
  6677     This function parses the XML document from the byte array \a
       
  6678     data and sets it as the content of the document. It tries to
       
  6679     detect the encoding of the document as required by the XML
       
  6680     specification.
       
  6681 
       
  6682     If \a namespaceProcessing is true, the parser recognizes
       
  6683     namespaces in the XML file and sets the prefix name, local name
       
  6684     and namespace URI to appropriate values. If \a namespaceProcessing
       
  6685     is false, the parser does no namespace processing when it reads
       
  6686     the XML file.
       
  6687 
       
  6688     If a parse error occurs, this function returns false and the error
       
  6689     message is placed in \c{*}\a{errorMsg}, the line number in
       
  6690     \c{*}\a{errorLine} and the column number in \c{*}\a{errorColumn}
       
  6691     (unless the associated pointer is set to 0); otherwise this
       
  6692     function returns true. The various error messages are described in
       
  6693     the QXmlParseException class documentation. Note that, if you
       
  6694     want to display these error messages to your application's users,
       
  6695     they will be displayed in English unless they are explicitly
       
  6696     translated.
       
  6697 
       
  6698     If \a namespaceProcessing is true, the function QDomNode::prefix()
       
  6699     returns a string for all elements and attributes. It returns an
       
  6700     empty string if the element or attribute has no prefix.
       
  6701 
       
  6702     Text nodes consisting only of whitespace are stripped and won't
       
  6703     appear in the QDomDocument. If this behavior is not desired,
       
  6704     one can use the setContent() overload that allows a QXmlReader to be
       
  6705     supplied.
       
  6706 
       
  6707     If \a namespaceProcessing is false, the functions
       
  6708     QDomNode::prefix(), QDomNode::localName() and
       
  6709     QDomNode::namespaceURI() return an empty string.
       
  6710 
       
  6711     Entity references are handled as follows:
       
  6712     \list
       
  6713     \o References to internal general entities and character entities occurring in the
       
  6714         content are included. The result is a QDomText node with the references replaced
       
  6715         by their corresponding entity values.
       
  6716     \o References to parameter entities occurring in the internal subset are included.
       
  6717         The result is a QDomDocumentType node which contains entity and notation declarations
       
  6718         with the references replaced by their corresponding entity values.
       
  6719     \o Any general parsed entity reference which is not defined in the internal subset and
       
  6720         which occurs in the content is represented as a QDomEntityReference node.
       
  6721     \o Any parsed entity reference which is not defined in the internal subset and which
       
  6722         occurs outside of the content is replaced with an empty string.
       
  6723     \o Any unparsed entity reference is replaced with an empty string.
       
  6724     \endlist
       
  6725 
       
  6726     \sa QDomNode::namespaceURI() QDomNode::localName()
       
  6727     QDomNode::prefix() QString::isNull() QString::isEmpty()
       
  6728 */
       
  6729 bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6730 {
       
  6731     if (!impl)
       
  6732         impl = new QDomDocumentPrivate();
       
  6733     QBuffer buf;
       
  6734     buf.setData(data);
       
  6735     QXmlInputSource source(&buf);
       
  6736     return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn);
       
  6737 }
       
  6738 
       
  6739 /*!
       
  6740     \overload
       
  6741 
       
  6742     This function reads the XML document from the IO device \a dev, returning
       
  6743     true if the content was successfully parsed; otherwise returns false.
       
  6744 */
       
  6745 bool QDomDocument::setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6746 {
       
  6747     if (!impl)
       
  6748         impl = new QDomDocumentPrivate();
       
  6749     QXmlInputSource source(dev);
       
  6750     return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn);
       
  6751 }
       
  6752 
       
  6753 /*!
       
  6754     \overload
       
  6755     \since 4.5
       
  6756 
       
  6757     This function reads the XML document from the QXmlInputSource \a source,
       
  6758     returning true if the content was successfully parsed; otherwise returns false.
       
  6759 
       
  6760 */
       
  6761 bool QDomDocument::setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6762 {
       
  6763     if (!impl)
       
  6764         impl = new QDomDocumentPrivate();
       
  6765     QXmlSimpleReader reader;
       
  6766     initializeReader(reader, namespaceProcessing);
       
  6767     return IMPL->setContent(source, &reader, errorMsg, errorLine, errorColumn);
       
  6768 }
       
  6769 
       
  6770 /*!
       
  6771     \overload
       
  6772 
       
  6773     This function reads the XML document from the string \a text, returning
       
  6774     true if the content was successfully parsed; otherwise returns false.
       
  6775     Since \a text is already a Unicode string, no encoding detection
       
  6776     is performed.
       
  6777 
       
  6778     No namespace processing is performed either.
       
  6779 */
       
  6780 bool QDomDocument::setContent(const QString& text, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6781 {
       
  6782     return setContent(text, false, errorMsg, errorLine, errorColumn);
       
  6783 }
       
  6784 
       
  6785 /*!
       
  6786     \overload
       
  6787 
       
  6788     This function reads the XML document from the byte array \a buffer,
       
  6789     returning true if the content was successfully parsed; otherwise returns
       
  6790     false.
       
  6791 
       
  6792     No namespace processing is performed.
       
  6793 */
       
  6794 bool QDomDocument::setContent(const QByteArray& buffer, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6795 {
       
  6796     return setContent(buffer, false, errorMsg, errorLine, errorColumn);
       
  6797 }
       
  6798 
       
  6799 /*!
       
  6800     \overload
       
  6801 
       
  6802     This function reads the XML document from the IO device \a dev, returning
       
  6803     true if the content was successfully parsed; otherwise returns false.
       
  6804 
       
  6805     No namespace processing is performed.
       
  6806 */
       
  6807 bool QDomDocument::setContent(QIODevice* dev, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6808 {
       
  6809     return setContent(dev, false, errorMsg, errorLine, errorColumn);
       
  6810 }
       
  6811 
       
  6812 /*!
       
  6813     \overload
       
  6814 
       
  6815     This function reads the XML document from the QXmlInputSource \a source and
       
  6816     parses it with the QXmlReader \a reader, returning true if the content was
       
  6817     successfully parsed; otherwise returns false.
       
  6818 
       
  6819     This function doesn't change the features of the \a reader. If you want to
       
  6820     use certain features for parsing you can use this function to set up the
       
  6821     reader appropriately.
       
  6822 
       
  6823     \sa QXmlSimpleReader
       
  6824 */
       
  6825 bool QDomDocument::setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6826 {
       
  6827     if (!impl)
       
  6828         impl = new QDomDocumentPrivate();
       
  6829     return IMPL->setContent(source, reader, errorMsg, errorLine, errorColumn);
       
  6830 }
       
  6831 
       
  6832 /*!
       
  6833     Converts the parsed document back to its textual representation.
       
  6834 
       
  6835     This function uses \a indent as the amount of space to indent
       
  6836     subelements.
       
  6837 
       
  6838     If \a indent is -1, no whitespace at all is added.
       
  6839 */
       
  6840 QString QDomDocument::toString(int indent) const
       
  6841 {
       
  6842     QString str;
       
  6843     QTextStream s(&str, QIODevice::WriteOnly);
       
  6844     save(s, indent);
       
  6845     return str;
       
  6846 }
       
  6847 
       
  6848 /*!
       
  6849     Converts the parsed document back to its textual representation
       
  6850     and returns a QByteArray containing the data encoded as UTF-8.
       
  6851 
       
  6852     This function uses \a indent as the amount of space to indent
       
  6853     subelements.
       
  6854 
       
  6855     \sa toString()
       
  6856 */
       
  6857 QByteArray QDomDocument::toByteArray(int indent) const
       
  6858 {
       
  6859     // ### if there is an encoding specified in the xml declaration, this
       
  6860     // encoding declaration should be changed to utf8
       
  6861     return toString(indent).toUtf8();
       
  6862 }
       
  6863 
       
  6864 
       
  6865 /*!
       
  6866     Returns the document type of this document.
       
  6867 */
       
  6868 QDomDocumentType QDomDocument::doctype() const
       
  6869 {
       
  6870     if (!impl)
       
  6871         return QDomDocumentType();
       
  6872     return QDomDocumentType(IMPL->doctype());
       
  6873 }
       
  6874 
       
  6875 /*!
       
  6876     Returns a QDomImplementation object.
       
  6877 */
       
  6878 QDomImplementation QDomDocument::implementation() const
       
  6879 {
       
  6880     if (!impl)
       
  6881         return QDomImplementation();
       
  6882     return QDomImplementation(IMPL->implementation());
       
  6883 }
       
  6884 
       
  6885 /*!
       
  6886     Returns the root element of the document.
       
  6887 */
       
  6888 QDomElement QDomDocument::documentElement() const
       
  6889 {
       
  6890     if (!impl)
       
  6891         return QDomElement();
       
  6892     return QDomElement(IMPL->documentElement());
       
  6893 }
       
  6894 
       
  6895 /*!
       
  6896     Creates a new element called \a tagName that can be inserted into
       
  6897     the DOM tree, e.g. using QDomNode::appendChild().
       
  6898 
       
  6899     If \a tagName is not a valid XML name, the behavior of this function is governed
       
  6900     by QDomImplementation::InvalidDataPolicy.
       
  6901 
       
  6902     \sa createElementNS() QDomNode::appendChild() QDomNode::insertBefore()
       
  6903     QDomNode::insertAfter()
       
  6904 */
       
  6905 QDomElement QDomDocument::createElement(const QString& tagName)
       
  6906 {
       
  6907     if (!impl)
       
  6908         impl = new QDomDocumentPrivate();
       
  6909     return QDomElement(IMPL->createElement(tagName));
       
  6910 }
       
  6911 
       
  6912 /*!
       
  6913     Creates a new document fragment, that can be used to hold parts of
       
  6914     the document, e.g. when doing complex manipulations of the
       
  6915     document tree.
       
  6916 */
       
  6917 QDomDocumentFragment QDomDocument::createDocumentFragment()
       
  6918 {
       
  6919     if (!impl)
       
  6920         impl = new QDomDocumentPrivate();
       
  6921     return QDomDocumentFragment(IMPL->createDocumentFragment());
       
  6922 }
       
  6923 
       
  6924 /*!
       
  6925     Creates a text node for the string \a value that can be inserted
       
  6926     into the document tree, e.g. using QDomNode::appendChild().
       
  6927 
       
  6928     If \a value contains characters which cannot be stored as character
       
  6929     data of an XML document (even in the form of character references), the
       
  6930     behavior of this function is governed by QDomImplementation::InvalidDataPolicy.
       
  6931 
       
  6932     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6933 */
       
  6934 QDomText QDomDocument::createTextNode(const QString& value)
       
  6935 {
       
  6936     if (!impl)
       
  6937         impl = new QDomDocumentPrivate();
       
  6938     return QDomText(IMPL->createTextNode(value));
       
  6939 }
       
  6940 
       
  6941 /*!
       
  6942     Creates a new comment for the string \a value that can be inserted
       
  6943     into the document, e.g. using QDomNode::appendChild().
       
  6944 
       
  6945     If \a value contains characters which cannot be stored in an XML comment,
       
  6946     the behavior of this function is governed by QDomImplementation::InvalidDataPolicy.
       
  6947 
       
  6948     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6949 */
       
  6950 QDomComment QDomDocument::createComment(const QString& value)
       
  6951 {
       
  6952     if (!impl)
       
  6953         impl = new QDomDocumentPrivate();
       
  6954     return QDomComment(IMPL->createComment(value));
       
  6955 }
       
  6956 
       
  6957 /*!
       
  6958     Creates a new CDATA section for the string \a value that can be
       
  6959     inserted into the document, e.g. using QDomNode::appendChild().
       
  6960 
       
  6961     If \a value contains characters which cannot be stored in a CDATA section,
       
  6962     the behavior of this function is governed by
       
  6963     QDomImplementation::InvalidDataPolicy.
       
  6964 
       
  6965     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6966 */
       
  6967 QDomCDATASection QDomDocument::createCDATASection(const QString& value)
       
  6968 {
       
  6969     if (!impl)
       
  6970         impl = new QDomDocumentPrivate();
       
  6971     return QDomCDATASection(IMPL->createCDATASection(value));
       
  6972 }
       
  6973 
       
  6974 /*!
       
  6975     Creates a new processing instruction that can be inserted into the
       
  6976     document, e.g. using QDomNode::appendChild(). This function sets
       
  6977     the target for the processing instruction to \a target and the
       
  6978     data to \a data.
       
  6979 
       
  6980     If \a target is not a valid XML name, or data if contains characters which cannot
       
  6981     appear in a processing instruction, the behavior of this function is governed by
       
  6982     QDomImplementation::InvalidDataPolicy.
       
  6983 
       
  6984     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6985 */
       
  6986 QDomProcessingInstruction QDomDocument::createProcessingInstruction(const QString& target,
       
  6987                                                                     const QString& data)
       
  6988 {
       
  6989     if (!impl)
       
  6990         impl = new QDomDocumentPrivate();
       
  6991     return QDomProcessingInstruction(IMPL->createProcessingInstruction(target, data));
       
  6992 }
       
  6993 
       
  6994 
       
  6995 /*!
       
  6996     Creates a new attribute called \a name that can be inserted into
       
  6997     an element, e.g. using QDomElement::setAttributeNode().
       
  6998 
       
  6999     If \a name is not a valid XML name, the behavior of this function is governed by
       
  7000     QDomImplementation::InvalidDataPolicy.
       
  7001 
       
  7002     \sa createAttributeNS()
       
  7003 */
       
  7004 QDomAttr QDomDocument::createAttribute(const QString& name)
       
  7005 {
       
  7006     if (!impl)
       
  7007         impl = new QDomDocumentPrivate();
       
  7008     return QDomAttr(IMPL->createAttribute(name));
       
  7009 }
       
  7010 
       
  7011 /*!
       
  7012     Creates a new entity reference called \a name that can be inserted
       
  7013     into the document, e.g. using QDomNode::appendChild().
       
  7014 
       
  7015     If \a name is not a valid XML name, the behavior of this function is governed by
       
  7016     QDomImplementation::InvalidDataPolicy.
       
  7017 
       
  7018     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  7019 */
       
  7020 QDomEntityReference QDomDocument::createEntityReference(const QString& name)
       
  7021 {
       
  7022     if (!impl)
       
  7023         impl = new QDomDocumentPrivate();
       
  7024     return QDomEntityReference(IMPL->createEntityReference(name));
       
  7025 }
       
  7026 
       
  7027 /*!
       
  7028     Returns a QDomNodeList, that contains all the elements in the
       
  7029     document with the name \a tagname. The order of the node list is
       
  7030     the order they are encountered in a preorder traversal of the
       
  7031     element tree.
       
  7032 
       
  7033     \sa elementsByTagNameNS() QDomElement::elementsByTagName()
       
  7034 */
       
  7035 QDomNodeList QDomDocument::elementsByTagName(const QString& tagname) const
       
  7036 {
       
  7037     return QDomNodeList(new QDomNodeListPrivate(impl, tagname));
       
  7038 }
       
  7039 
       
  7040 /*!
       
  7041     Imports the node \a importedNode from another document to this
       
  7042     document. \a importedNode remains in the original document; this
       
  7043     function creates a copy that can be used within this document.
       
  7044 
       
  7045     This function returns the imported node that belongs to this
       
  7046     document. The returned node has no parent. It is not possible to
       
  7047     import QDomDocument and QDomDocumentType nodes. In those cases
       
  7048     this function returns a \link QDomNode::isNull() null node\endlink.
       
  7049 
       
  7050     If \a deep is true, this function imports not only the node \a
       
  7051     importedNode but its whole subtree; if it is false, only the \a
       
  7052     importedNode is imported. The argument \a deep has no effect on
       
  7053     QDomAttr and QDomEntityReference nodes, since the descendants of
       
  7054     QDomAttr nodes are always imported and those of
       
  7055     QDomEntityReference nodes are never imported.
       
  7056 
       
  7057     The behavior of this function is slightly different depending on
       
  7058     the node types:
       
  7059     \table
       
  7060     \header \i Node Type \i Behavior
       
  7061     \row \i QDomAttr
       
  7062          \i The owner element is set to 0 and the specified flag is
       
  7063             set to true in the generated attribute. The whole subtree
       
  7064             of \a importedNode is always imported for attribute nodes:
       
  7065             \a deep has no effect.
       
  7066     \row \i QDomDocument
       
  7067          \i Document nodes cannot be imported.
       
  7068     \row \i QDomDocumentFragment
       
  7069          \i If \a deep is true, this function imports the whole
       
  7070             document fragment; otherwise it only generates an empty
       
  7071             document fragment.
       
  7072     \row \i QDomDocumentType
       
  7073          \i Document type nodes cannot be imported.
       
  7074     \row \i QDomElement
       
  7075          \i Attributes for which QDomAttr::specified() is true are
       
  7076             also imported, other attributes are not imported. If \a
       
  7077             deep is true, this function also imports the subtree of \a
       
  7078             importedNode; otherwise it imports only the element node
       
  7079             (and some attributes, see above).
       
  7080     \row \i QDomEntity
       
  7081          \i Entity nodes can be imported, but at the moment there is
       
  7082             no way to use them since the document type is read-only in
       
  7083             DOM level 2.
       
  7084     \row \i QDomEntityReference
       
  7085          \i Descendants of entity reference nodes are never imported:
       
  7086             \a deep has no effect.
       
  7087     \row \i QDomNotation
       
  7088          \i Notation nodes can be imported, but at the moment there is
       
  7089             no way to use them since the document type is read-only in
       
  7090             DOM level 2.
       
  7091     \row \i QDomProcessingInstruction
       
  7092          \i The target and value of the processing instruction is
       
  7093             copied to the new node.
       
  7094     \row \i QDomText
       
  7095          \i The text is copied to the new node.
       
  7096     \row \i QDomCDATASection
       
  7097          \i The text is copied to the new node.
       
  7098     \row \i QDomComment
       
  7099          \i The text is copied to the new node.
       
  7100     \endtable
       
  7101 
       
  7102     \sa QDomElement::setAttribute() QDomNode::insertBefore()
       
  7103         QDomNode::insertAfter() QDomNode::replaceChild() QDomNode::removeChild()
       
  7104         QDomNode::appendChild()
       
  7105 */
       
  7106 QDomNode QDomDocument::importNode(const QDomNode& importedNode, bool deep)
       
  7107 {
       
  7108     if (!impl)
       
  7109         impl = new QDomDocumentPrivate();
       
  7110     return QDomNode(IMPL->importNode(importedNode.impl, deep));
       
  7111 }
       
  7112 
       
  7113 /*!
       
  7114     Creates a new element with namespace support that can be inserted
       
  7115     into the DOM tree. The name of the element is \a qName and the
       
  7116     namespace URI is \a nsURI. This function also sets
       
  7117     QDomNode::prefix() and QDomNode::localName() to appropriate values
       
  7118     (depending on \a qName).
       
  7119 
       
  7120     If \a qName is an empty string, returns a null element regardless of
       
  7121     whether the invalid data policy is set.
       
  7122 
       
  7123     \sa createElement()
       
  7124 */
       
  7125 QDomElement QDomDocument::createElementNS(const QString& nsURI, const QString& qName)
       
  7126 {
       
  7127     if (!impl)
       
  7128         impl = new QDomDocumentPrivate();
       
  7129     return QDomElement(IMPL->createElementNS(nsURI, qName));
       
  7130 }
       
  7131 
       
  7132 /*!
       
  7133     Creates a new attribute with namespace support that can be
       
  7134     inserted into an element. The name of the attribute is \a qName
       
  7135     and the namespace URI is \a nsURI. This function also sets
       
  7136     QDomNode::prefix() and QDomNode::localName() to appropriate values
       
  7137     (depending on \a qName).
       
  7138 
       
  7139     If \a qName is not a valid XML name, the behavior of this function is governed by
       
  7140     QDomImplementation::InvalidDataPolicy.
       
  7141 
       
  7142     \sa createAttribute()
       
  7143 */
       
  7144 QDomAttr QDomDocument::createAttributeNS(const QString& nsURI, const QString& qName)
       
  7145 {
       
  7146     if (!impl)
       
  7147         impl = new QDomDocumentPrivate();
       
  7148     return QDomAttr(IMPL->createAttributeNS(nsURI, qName));
       
  7149 }
       
  7150 
       
  7151 /*!
       
  7152     Returns a QDomNodeList that contains all the elements in the
       
  7153     document with the local name \a localName and a namespace URI of
       
  7154     \a nsURI. The order of the node list is the order they are
       
  7155     encountered in a preorder traversal of the element tree.
       
  7156 
       
  7157     \sa elementsByTagName() QDomElement::elementsByTagNameNS()
       
  7158 */
       
  7159 QDomNodeList QDomDocument::elementsByTagNameNS(const QString& nsURI, const QString& localName)
       
  7160 {
       
  7161     return QDomNodeList(new QDomNodeListPrivate(impl, nsURI, localName));
       
  7162 }
       
  7163 
       
  7164 /*!
       
  7165     Returns the element whose ID is equal to \a elementId. If no
       
  7166     element with the ID was found, this function returns a \link
       
  7167     QDomNode::isNull() null element\endlink.
       
  7168 
       
  7169     Since the QDomClasses do not know which attributes are element
       
  7170     IDs, this function returns always a \link QDomNode::isNull() null
       
  7171     element\endlink. This may change in a future version.
       
  7172 */
       
  7173 QDomElement QDomDocument::elementById(const QString& /*elementId*/)
       
  7174 {
       
  7175     qWarning("elementById() is not implemented and will always return a null node.");
       
  7176     return QDomElement();
       
  7177 }
       
  7178 
       
  7179 /*!
       
  7180     \fn QDomNode::NodeType QDomDocument::nodeType() const
       
  7181 
       
  7182     Returns \c DocumentNode.
       
  7183 */
       
  7184 
       
  7185 #undef IMPL
       
  7186 
       
  7187 /**************************************************************
       
  7188  *
       
  7189  * Node casting functions
       
  7190  *
       
  7191  **************************************************************/
       
  7192 
       
  7193 /*!
       
  7194     Converts a QDomNode into a QDomAttr. If the node is not an
       
  7195     attribute, the returned object will be \link QDomNode::isNull()
       
  7196     null\endlink.
       
  7197 
       
  7198     \sa isAttr()
       
  7199 */
       
  7200 QDomAttr QDomNode::toAttr() const
       
  7201 {
       
  7202     if (impl && impl->isAttr())
       
  7203         return QDomAttr(((QDomAttrPrivate*)impl));
       
  7204     return QDomAttr();
       
  7205 }
       
  7206 
       
  7207 /*!
       
  7208     Converts a QDomNode into a QDomCDATASection. If the node is not a
       
  7209     CDATA section, the returned object will be \link
       
  7210     QDomNode::isNull() null\endlink.
       
  7211 
       
  7212     \sa isCDATASection()
       
  7213 */
       
  7214 QDomCDATASection QDomNode::toCDATASection() const
       
  7215 {
       
  7216     if (impl && impl->isCDATASection())
       
  7217         return QDomCDATASection(((QDomCDATASectionPrivate*)impl));
       
  7218     return QDomCDATASection();
       
  7219 }
       
  7220 
       
  7221 /*!
       
  7222     Converts a QDomNode into a QDomDocumentFragment. If the node is
       
  7223     not a document fragment the returned object will be \link
       
  7224     QDomNode::isNull() null\endlink.
       
  7225 
       
  7226     \sa isDocumentFragment()
       
  7227 */
       
  7228 QDomDocumentFragment QDomNode::toDocumentFragment() const
       
  7229 {
       
  7230     if (impl && impl->isDocumentFragment())
       
  7231         return QDomDocumentFragment(((QDomDocumentFragmentPrivate*)impl));
       
  7232     return QDomDocumentFragment();
       
  7233 }
       
  7234 
       
  7235 /*!
       
  7236     Converts a QDomNode into a QDomDocument. If the node is not a
       
  7237     document the returned object will be \link QDomNode::isNull()
       
  7238     null\endlink.
       
  7239 
       
  7240     \sa isDocument()
       
  7241 */
       
  7242 QDomDocument QDomNode::toDocument() const
       
  7243 {
       
  7244     if (impl && impl->isDocument())
       
  7245         return QDomDocument(((QDomDocumentPrivate*)impl));
       
  7246     return QDomDocument();
       
  7247 }
       
  7248 
       
  7249 /*!
       
  7250     Converts a QDomNode into a QDomDocumentType. If the node is not a
       
  7251     document type the returned object will be \link QDomNode::isNull()
       
  7252     null\endlink.
       
  7253 
       
  7254     \sa isDocumentType()
       
  7255 */
       
  7256 QDomDocumentType QDomNode::toDocumentType() const
       
  7257 {
       
  7258     if (impl && impl->isDocumentType())
       
  7259         return QDomDocumentType(((QDomDocumentTypePrivate*)impl));
       
  7260     return QDomDocumentType();
       
  7261 }
       
  7262 
       
  7263 /*!
       
  7264     Converts a QDomNode into a QDomElement. If the node is not an
       
  7265     element the returned object will be \link QDomNode::isNull()
       
  7266     null\endlink.
       
  7267 
       
  7268     \sa isElement()
       
  7269 */
       
  7270 QDomElement QDomNode::toElement() const
       
  7271 {
       
  7272     if (impl && impl->isElement())
       
  7273         return QDomElement(((QDomElementPrivate*)impl));
       
  7274     return QDomElement();
       
  7275 }
       
  7276 
       
  7277 /*!
       
  7278     Converts a QDomNode into a QDomEntityReference. If the node is not
       
  7279     an entity reference, the returned object will be \link
       
  7280     QDomNode::isNull() null\endlink.
       
  7281 
       
  7282     \sa isEntityReference()
       
  7283 */
       
  7284 QDomEntityReference QDomNode::toEntityReference() const
       
  7285 {
       
  7286     if (impl && impl->isEntityReference())
       
  7287         return QDomEntityReference(((QDomEntityReferencePrivate*)impl));
       
  7288     return QDomEntityReference();
       
  7289 }
       
  7290 
       
  7291 /*!
       
  7292     Converts a QDomNode into a QDomText. If the node is not a text,
       
  7293     the returned object will be \link QDomNode::isNull() null\endlink.
       
  7294 
       
  7295     \sa isText()
       
  7296 */
       
  7297 QDomText QDomNode::toText() const
       
  7298 {
       
  7299     if (impl && impl->isText())
       
  7300         return QDomText(((QDomTextPrivate*)impl));
       
  7301     return QDomText();
       
  7302 }
       
  7303 
       
  7304 /*!
       
  7305     Converts a QDomNode into a QDomEntity. If the node is not an
       
  7306     entity the returned object will be \link QDomNode::isNull()
       
  7307     null\endlink.
       
  7308 
       
  7309     \sa isEntity()
       
  7310 */
       
  7311 QDomEntity QDomNode::toEntity() const
       
  7312 {
       
  7313     if (impl && impl->isEntity())
       
  7314         return QDomEntity(((QDomEntityPrivate*)impl));
       
  7315     return QDomEntity();
       
  7316 }
       
  7317 
       
  7318 /*!
       
  7319     Converts a QDomNode into a QDomNotation. If the node is not a
       
  7320     notation the returned object will be \link QDomNode::isNull()
       
  7321     null\endlink.
       
  7322 
       
  7323     \sa isNotation()
       
  7324 */
       
  7325 QDomNotation QDomNode::toNotation() const
       
  7326 {
       
  7327     if (impl && impl->isNotation())
       
  7328         return QDomNotation(((QDomNotationPrivate*)impl));
       
  7329     return QDomNotation();
       
  7330 }
       
  7331 
       
  7332 /*!
       
  7333     Converts a QDomNode into a QDomProcessingInstruction. If the node
       
  7334     is not a processing instruction the returned object will be \link
       
  7335     QDomNode::isNull() null\endlink.
       
  7336 
       
  7337     \sa isProcessingInstruction()
       
  7338 */
       
  7339 QDomProcessingInstruction QDomNode::toProcessingInstruction() const
       
  7340 {
       
  7341     if (impl && impl->isProcessingInstruction())
       
  7342         return QDomProcessingInstruction(((QDomProcessingInstructionPrivate*)impl));
       
  7343     return QDomProcessingInstruction();
       
  7344 }
       
  7345 
       
  7346 /*!
       
  7347     Converts a QDomNode into a QDomCharacterData. If the node is not a
       
  7348     character data node the returned object will be \link
       
  7349     QDomNode::isNull() null\endlink.
       
  7350 
       
  7351     \sa isCharacterData()
       
  7352 */
       
  7353 QDomCharacterData QDomNode::toCharacterData() const
       
  7354 {
       
  7355     if (impl && impl->isCharacterData())
       
  7356         return QDomCharacterData(((QDomCharacterDataPrivate*)impl));
       
  7357     return QDomCharacterData();
       
  7358 }
       
  7359 
       
  7360 /*!
       
  7361     Converts a QDomNode into a QDomComment. If the node is not a
       
  7362     comment the returned object will be \link QDomNode::isNull()
       
  7363     null\endlink.
       
  7364 
       
  7365     \sa isComment()
       
  7366 */
       
  7367 QDomComment QDomNode::toComment() const
       
  7368 {
       
  7369     if (impl && impl->isComment())
       
  7370         return QDomComment(((QDomCommentPrivate*)impl));
       
  7371     return QDomComment();
       
  7372 }
       
  7373 
       
  7374 /**************************************************************
       
  7375  *
       
  7376  * QDomHandler
       
  7377  *
       
  7378  **************************************************************/
       
  7379 
       
  7380 QDomHandler::QDomHandler(QDomDocumentPrivate* adoc, bool namespaceProcessing)
       
  7381     : errorLine(0), errorColumn(0), doc(adoc), node(adoc), cdata(false),
       
  7382         nsProcessing(namespaceProcessing), locator(0)
       
  7383 {
       
  7384 }
       
  7385 
       
  7386 QDomHandler::~QDomHandler()
       
  7387 {
       
  7388 }
       
  7389 
       
  7390 bool QDomHandler::endDocument()
       
  7391 {
       
  7392     // ### is this really necessary? (rms)
       
  7393     if (node != doc)
       
  7394         return false;
       
  7395     return true;
       
  7396 }
       
  7397 
       
  7398 bool QDomHandler::startDTD(const QString& name, const QString& publicId, const QString& systemId)
       
  7399 {
       
  7400     doc->doctype()->name = name;
       
  7401     doc->doctype()->publicId = publicId;
       
  7402     doc->doctype()->systemId = systemId;
       
  7403     return true;
       
  7404 }
       
  7405 
       
  7406 bool QDomHandler::startElement(const QString& nsURI, const QString&, const QString& qName, const QXmlAttributes& atts)
       
  7407 {
       
  7408     // tag name
       
  7409     QDomNodePrivate* n;
       
  7410     if (nsProcessing) {
       
  7411         n = doc->createElementNS(nsURI, qName);
       
  7412     } else {
       
  7413         n = doc->createElement(qName);
       
  7414     }
       
  7415 
       
  7416     if (n)
       
  7417         n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7418 
       
  7419     node->appendChild(n);
       
  7420     node = n;
       
  7421 
       
  7422     // attributes
       
  7423     for (int i=0; i<atts.length(); i++)
       
  7424     {
       
  7425         if (nsProcessing) {
       
  7426             ((QDomElementPrivate*)node)->setAttributeNS(atts.uri(i), atts.qName(i), atts.value(i));
       
  7427         } else {
       
  7428             ((QDomElementPrivate*)node)->setAttribute(atts.qName(i), atts.value(i));
       
  7429         }
       
  7430     }
       
  7431 
       
  7432     return true;
       
  7433 }
       
  7434 
       
  7435 bool QDomHandler::endElement(const QString&, const QString&, const QString&)
       
  7436 {
       
  7437     if (!node || node == doc)
       
  7438         return false;
       
  7439     node = node->parent();
       
  7440 
       
  7441     return true;
       
  7442 }
       
  7443 
       
  7444 bool QDomHandler::characters(const QString&  ch)
       
  7445 {
       
  7446     // No text as child of some document
       
  7447     if (node == doc)
       
  7448         return false;
       
  7449 
       
  7450     QScopedPointer<QDomNodePrivate> n;
       
  7451     if (cdata) {
       
  7452         n.reset(doc->createCDATASection(ch));
       
  7453     } else if (!entityName.isEmpty()) {
       
  7454         QScopedPointer<QDomEntityPrivate> e(new QDomEntityPrivate(doc, 0, entityName,
       
  7455                 QString(), QString(), QString()));
       
  7456         e->value = ch;
       
  7457         doc->doctype()->appendChild(e.data());
       
  7458         e.take();
       
  7459         n.reset(doc->createEntityReference(entityName));
       
  7460     } else {
       
  7461         n.reset(doc->createTextNode(ch));
       
  7462     }
       
  7463     n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7464     node->appendChild(n.data());
       
  7465     n.take();
       
  7466 
       
  7467     return true;
       
  7468 }
       
  7469 
       
  7470 bool QDomHandler::processingInstruction(const QString& target, const QString& data)
       
  7471 {
       
  7472     QDomNodePrivate *n;
       
  7473     n = doc->createProcessingInstruction(target, data);
       
  7474     if (n) {
       
  7475         n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7476         node->appendChild(n);
       
  7477         return true;
       
  7478     }
       
  7479     else
       
  7480         return false;
       
  7481 }
       
  7482 
       
  7483 extern bool qt_xml_skipped_entity_in_content;
       
  7484 bool QDomHandler::skippedEntity(const QString& name)
       
  7485 {
       
  7486     // we can only handle inserting entity references into content
       
  7487     if (!qt_xml_skipped_entity_in_content)
       
  7488         return true;
       
  7489 
       
  7490     QDomNodePrivate *n = doc->createEntityReference(name);
       
  7491     n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7492     node->appendChild(n);
       
  7493     return true;
       
  7494 }
       
  7495 
       
  7496 bool QDomHandler::fatalError(const QXmlParseException& exception)
       
  7497 {
       
  7498     errorMsg = exception.message();
       
  7499     errorLine =  exception.lineNumber();
       
  7500     errorColumn =  exception.columnNumber();
       
  7501     return QXmlDefaultHandler::fatalError(exception);
       
  7502 }
       
  7503 
       
  7504 bool QDomHandler::startCDATA()
       
  7505 {
       
  7506     cdata = true;
       
  7507     return true;
       
  7508 }
       
  7509 
       
  7510 bool QDomHandler::endCDATA()
       
  7511 {
       
  7512     cdata = false;
       
  7513     return true;
       
  7514 }
       
  7515 
       
  7516 bool QDomHandler::startEntity(const QString &name)
       
  7517 {
       
  7518     entityName = name;
       
  7519     return true;
       
  7520 }
       
  7521 
       
  7522 bool QDomHandler::endEntity(const QString &)
       
  7523 {
       
  7524     entityName.clear();
       
  7525     return true;
       
  7526 }
       
  7527 
       
  7528 bool QDomHandler::comment(const QString& ch)
       
  7529 {
       
  7530     QDomNodePrivate *n;
       
  7531     n = doc->createComment(ch);
       
  7532     n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7533     node->appendChild(n);
       
  7534     return true;
       
  7535 }
       
  7536 
       
  7537 bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName)
       
  7538 {
       
  7539     QDomEntityPrivate* e = new QDomEntityPrivate(doc, 0, name,
       
  7540             publicId, systemId, notationName);
       
  7541     doc->doctype()->appendChild(e);
       
  7542     return true;
       
  7543 }
       
  7544 
       
  7545 bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId)
       
  7546 {
       
  7547     return unparsedEntityDecl(name, publicId, systemId, QString());
       
  7548 }
       
  7549 
       
  7550 bool QDomHandler::notationDecl(const QString & name, const QString & publicId, const QString & systemId)
       
  7551 {
       
  7552     QDomNotationPrivate* n = new QDomNotationPrivate(doc, 0, name, publicId, systemId);
       
  7553     doc->doctype()->appendChild(n);
       
  7554     return true;
       
  7555 }
       
  7556 
       
  7557 void QDomHandler::setDocumentLocator(QXmlLocator *locator)
       
  7558 {
       
  7559     this->locator = locator;
       
  7560 }
       
  7561 
       
  7562 QT_END_NAMESPACE
       
  7563 
       
  7564 #endif // QT_NO_DOM