src/xml/dom/qdom.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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     Calling this function on a null node(created, for example, with the
       
  2600     default constructor) does nothing.
       
  2601 
       
  2602     The DOM specification disallow inserting attribute nodes, but due
       
  2603     to historical reasons QDom accept them nevertheless.
       
  2604 
       
  2605     \sa insertBefore() insertAfter() replaceChild() removeChild()
       
  2606 */
       
  2607 QDomNode QDomNode::appendChild(const QDomNode& newChild)
       
  2608 {
       
  2609     if (!impl) {
       
  2610         qWarning("Calling appendChild() on a null node does nothing.");
       
  2611         return QDomNode();
       
  2612     }
       
  2613     return QDomNode(IMPL->appendChild(newChild.impl));
       
  2614 }
       
  2615 
       
  2616 /*!
       
  2617     Returns true if the node has one or more children; otherwise
       
  2618     returns false.
       
  2619 */
       
  2620 bool QDomNode::hasChildNodes() const
       
  2621 {
       
  2622     if (!impl)
       
  2623         return false;
       
  2624     return IMPL->first != 0;
       
  2625 }
       
  2626 
       
  2627 /*!
       
  2628     Returns true if this node is null (i.e. if it has no type or
       
  2629     contents); otherwise returns false.
       
  2630 */
       
  2631 bool QDomNode::isNull() const
       
  2632 {
       
  2633     return (impl == 0);
       
  2634 }
       
  2635 
       
  2636 /*!
       
  2637     Converts the node into a null node; if it was not a null node
       
  2638     before, its type and contents are deleted.
       
  2639 
       
  2640     \sa isNull()
       
  2641 */
       
  2642 void QDomNode::clear()
       
  2643 {
       
  2644     if (impl && !impl->ref.deref())
       
  2645         delete impl;
       
  2646     impl = 0;
       
  2647 }
       
  2648 
       
  2649 /*!
       
  2650     Returns the first direct child node for which nodeName() equals \a
       
  2651     name.
       
  2652 
       
  2653     If no such direct child exists, a \link isNull() null node\endlink
       
  2654     is returned.
       
  2655 
       
  2656     \sa nodeName()
       
  2657 */
       
  2658 QDomNode QDomNode::namedItem(const QString& name) const
       
  2659 {
       
  2660     if (!impl)
       
  2661         return QDomNode();
       
  2662     return QDomNode(impl->namedItem(name));
       
  2663 }
       
  2664 
       
  2665 /*!
       
  2666     Writes the XML representation of the node and all its children to
       
  2667     the stream \a str. This function uses \a indent as the amount of
       
  2668     space to indent the node.
       
  2669 
       
  2670     If this node is a document node, the encoding of text stream \a str's encoding is
       
  2671     set by treating a processing instruction by name "xml" as an XML declaration, if such a one exists,
       
  2672     and otherwise defaults to UTF-8. XML declarations are not processing instructions, but this
       
  2673     behavior exists for historical reasons. If this node is not a document node,
       
  2674     the text stream's encoding is used.
       
  2675 
       
  2676     If the document contains invalid XML characters or characters that cannot be
       
  2677     encoded in the given encoding, the result and behavior is undefined.
       
  2678 
       
  2679 */
       
  2680 void QDomNode::save(QTextStream& str, int indent) const
       
  2681 {
       
  2682     save(str, indent, QDomNode::EncodingFromDocument);
       
  2683 }
       
  2684 
       
  2685 /*!
       
  2686     If \a encodingPolicy is QDomNode::EncodingFromDocument, this function behaves as save(QTextStream &str, int indent).
       
  2687 
       
  2688     If \a encodingPolicy is EncodingFromTextStream and this node is a document node, this
       
  2689     function behaves as save(QTextStream &str, int indent) with the exception that the encoding
       
  2690     specified in the text stream \a str is used.
       
  2691 
       
  2692     If the document contains invalid XML characters or characters that cannot be
       
  2693     encoded in the given encoding, the result and behavior is undefined.
       
  2694 
       
  2695     \since 4.2
       
  2696  */
       
  2697 void QDomNode::save(QTextStream& str, int indent, EncodingPolicy encodingPolicy) const
       
  2698 {
       
  2699     if (!impl)
       
  2700         return;
       
  2701 
       
  2702     if(isDocument())
       
  2703         static_cast<const QDomDocumentPrivate *>(impl)->saveDocument(str, indent, encodingPolicy);
       
  2704     else
       
  2705         IMPL->save(str, 1, indent);
       
  2706 }
       
  2707 
       
  2708 /*!
       
  2709     \relates QDomNode
       
  2710 
       
  2711     Writes the XML representation of the node \a node and all its
       
  2712     children to the stream \a str.
       
  2713 */
       
  2714 QTextStream& operator<<(QTextStream& str, const QDomNode& node)
       
  2715 {
       
  2716     node.save(str, 1);
       
  2717 
       
  2718     return str;
       
  2719 }
       
  2720 
       
  2721 /*!
       
  2722     Returns true if the node is an attribute; otherwise returns false.
       
  2723 
       
  2724     If this function returns true, it does not imply that this object
       
  2725     is a QDomAttribute; you can get the QDomAttribute with
       
  2726     toAttribute().
       
  2727 
       
  2728     \sa toAttr()
       
  2729 */
       
  2730 bool QDomNode::isAttr() const
       
  2731 {
       
  2732     if(impl)
       
  2733         return impl->isAttr();
       
  2734     return false;
       
  2735 }
       
  2736 
       
  2737 /*!
       
  2738     Returns true if the node is a CDATA section; otherwise returns
       
  2739     false.
       
  2740 
       
  2741     If this function returns true, it does not imply that this object
       
  2742     is a QDomCDATASection; you can get the QDomCDATASection with
       
  2743     toCDATASection().
       
  2744 
       
  2745     \sa toCDATASection()
       
  2746 */
       
  2747 bool QDomNode::isCDATASection() const
       
  2748 {
       
  2749     if(impl)
       
  2750         return impl->isCDATASection();
       
  2751     return false;
       
  2752 }
       
  2753 
       
  2754 /*!
       
  2755     Returns true if the node is a document fragment; otherwise returns
       
  2756     false.
       
  2757 
       
  2758     If this function returns true, it does not imply that this object
       
  2759     is a QDomDocumentFragment; you can get the QDomDocumentFragment
       
  2760     with toDocumentFragment().
       
  2761 
       
  2762     \sa toDocumentFragment()
       
  2763 */
       
  2764 bool QDomNode::isDocumentFragment() const
       
  2765 {
       
  2766     if(impl)
       
  2767         return impl->isDocumentFragment();
       
  2768     return false;
       
  2769 }
       
  2770 
       
  2771 /*!
       
  2772     Returns true if the node is a document; otherwise returns false.
       
  2773 
       
  2774     If this function returns true, it does not imply that this object
       
  2775     is a QDomDocument; you can get the QDomDocument with toDocument().
       
  2776 
       
  2777     \sa toDocument()
       
  2778 */
       
  2779 bool QDomNode::isDocument() const
       
  2780 {
       
  2781     if(impl)
       
  2782         return impl->isDocument();
       
  2783     return false;
       
  2784 }
       
  2785 
       
  2786 /*!
       
  2787     Returns true if the node is a document type; otherwise returns
       
  2788     false.
       
  2789 
       
  2790     If this function returns true, it does not imply that this object
       
  2791     is a QDomDocumentType; you can get the QDomDocumentType with
       
  2792     toDocumentType().
       
  2793 
       
  2794     \sa toDocumentType()
       
  2795 */
       
  2796 bool QDomNode::isDocumentType() const
       
  2797 {
       
  2798     if(impl)
       
  2799         return impl->isDocumentType();
       
  2800     return false;
       
  2801 }
       
  2802 
       
  2803 /*!
       
  2804     Returns true if the node is an element; otherwise returns false.
       
  2805 
       
  2806     If this function returns true, it does not imply that this object
       
  2807     is a QDomElement; you can get the QDomElement with toElement().
       
  2808 
       
  2809     \sa toElement()
       
  2810 */
       
  2811 bool QDomNode::isElement() const
       
  2812 {
       
  2813     if(impl)
       
  2814         return impl->isElement();
       
  2815     return false;
       
  2816 }
       
  2817 
       
  2818 /*!
       
  2819     Returns true if the node is an entity reference; otherwise returns
       
  2820     false.
       
  2821 
       
  2822     If this function returns true, it does not imply that this object
       
  2823     is a QDomEntityReference; you can get the QDomEntityReference with
       
  2824     toEntityReference().
       
  2825 
       
  2826     \sa toEntityReference()
       
  2827 */
       
  2828 bool QDomNode::isEntityReference() const
       
  2829 {
       
  2830     if(impl)
       
  2831         return impl->isEntityReference();
       
  2832     return false;
       
  2833 }
       
  2834 
       
  2835 /*!
       
  2836     Returns true if the node is a text node; otherwise returns false.
       
  2837 
       
  2838     If this function returns true, it does not imply that this object
       
  2839     is a QDomText; you can get the QDomText with toText().
       
  2840 
       
  2841     \sa toText()
       
  2842 */
       
  2843 bool QDomNode::isText() const
       
  2844 {
       
  2845     if(impl)
       
  2846         return impl->isText();
       
  2847     return false;
       
  2848 }
       
  2849 
       
  2850 /*!
       
  2851     Returns true if the node is an entity; otherwise returns false.
       
  2852 
       
  2853     If this function returns true, it does not imply that this object
       
  2854     is a QDomEntity; you can get the QDomEntity with toEntity().
       
  2855 
       
  2856     \sa toEntity()
       
  2857 */
       
  2858 bool QDomNode::isEntity() const
       
  2859 {
       
  2860     if(impl)
       
  2861         return impl->isEntity();
       
  2862     return false;
       
  2863 }
       
  2864 
       
  2865 /*!
       
  2866     Returns true if the node is a notation; otherwise returns false.
       
  2867 
       
  2868     If this function returns true, it does not imply that this object
       
  2869     is a QDomNotation; you can get the QDomNotation with toNotation().
       
  2870 
       
  2871     \sa toNotation()
       
  2872 */
       
  2873 bool QDomNode::isNotation() const
       
  2874 {
       
  2875     if(impl)
       
  2876         return impl->isNotation();
       
  2877     return false;
       
  2878 }
       
  2879 
       
  2880 /*!
       
  2881     Returns true if the node is a processing instruction; otherwise
       
  2882     returns false.
       
  2883 
       
  2884     If this function returns true, it does not imply that this object
       
  2885     is a QDomProcessingInstruction; you can get the
       
  2886     QProcessingInstruction with toProcessingInstruction().
       
  2887 
       
  2888     \sa toProcessingInstruction()
       
  2889 */
       
  2890 bool QDomNode::isProcessingInstruction() const
       
  2891 {
       
  2892     if(impl)
       
  2893         return impl->isProcessingInstruction();
       
  2894     return false;
       
  2895 }
       
  2896 
       
  2897 /*!
       
  2898     Returns true if the node is a character data node; otherwise
       
  2899     returns false.
       
  2900 
       
  2901     If this function returns true, it does not imply that this object
       
  2902     is a QDomCharacterData; you can get the QDomCharacterData with
       
  2903     toCharacterData().
       
  2904 
       
  2905     \sa toCharacterData()
       
  2906 */
       
  2907 bool QDomNode::isCharacterData() const
       
  2908 {
       
  2909     if (impl)
       
  2910         return impl->isCharacterData();
       
  2911     return false;
       
  2912 }
       
  2913 
       
  2914 /*!
       
  2915     Returns true if the node is a comment; otherwise returns false.
       
  2916 
       
  2917     If this function returns true, it does not imply that this object
       
  2918     is a QDomComment; you can get the QDomComment with toComment().
       
  2919 
       
  2920     \sa toComment()
       
  2921 */
       
  2922 bool QDomNode::isComment() const
       
  2923 {
       
  2924     if (impl)
       
  2925         return impl->isComment();
       
  2926     return false;
       
  2927 }
       
  2928 
       
  2929 #undef IMPL
       
  2930 
       
  2931 /*!
       
  2932     Returns the first child element with tag name \a tagName if tagName is non-empty;
       
  2933     otherwise returns the first child element.  Returns a null element if no
       
  2934     such child exists.
       
  2935 
       
  2936     \sa lastChildElement() previousSiblingElement() nextSiblingElement()
       
  2937 */
       
  2938 
       
  2939 QDomElement QDomNode::firstChildElement(const QString &tagName) const
       
  2940 {
       
  2941     for (QDomNode child = firstChild(); !child.isNull(); child = child.nextSibling()) {
       
  2942         if (child.isElement()) {
       
  2943             QDomElement elt = child.toElement();
       
  2944             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  2945                 return elt;
       
  2946         }
       
  2947     }
       
  2948     return QDomElement();
       
  2949 }
       
  2950 
       
  2951 /*!
       
  2952     Returns the last child element with tag name \a tagName if tagName is non-empty;
       
  2953     otherwise returns the first child element. Returns a null element if no
       
  2954     such child exists.
       
  2955 
       
  2956     \sa firstChildElement() previousSiblingElement() nextSiblingElement()
       
  2957 */
       
  2958 
       
  2959 QDomElement QDomNode::lastChildElement(const QString &tagName) const
       
  2960 {
       
  2961     for (QDomNode child = lastChild(); !child.isNull(); child = child.previousSibling()) {
       
  2962         if (child.isElement()) {
       
  2963             QDomElement elt = child.toElement();
       
  2964             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  2965                 return elt;
       
  2966         }
       
  2967     }
       
  2968     return QDomElement();
       
  2969 }
       
  2970 
       
  2971 /*!
       
  2972     Returns the next sibilng element with tag name \a tagName if \a tagName
       
  2973     is non-empty; otherwise returns any next sibling element.
       
  2974     Returns a null element if no such sibling exists.
       
  2975 
       
  2976     \sa firstChildElement() previousSiblingElement() lastChildElement()
       
  2977 */
       
  2978 
       
  2979 QDomElement QDomNode::nextSiblingElement(const QString &tagName) const
       
  2980 {
       
  2981     for (QDomNode sib = nextSibling(); !sib.isNull(); sib = sib.nextSibling()) {
       
  2982         if (sib.isElement()) {
       
  2983             QDomElement elt = sib.toElement();
       
  2984             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  2985                 return elt;
       
  2986         }
       
  2987     }
       
  2988     return QDomElement();
       
  2989 }
       
  2990 
       
  2991 /*!
       
  2992     Returns the previous sibilng element with tag name \a tagName if \a tagName
       
  2993     is non-empty; otherwise returns any previous sibling element.
       
  2994     Returns a null element if no such sibling exists.
       
  2995 
       
  2996     \sa firstChildElement(), nextSiblingElement(), lastChildElement()
       
  2997 */
       
  2998 
       
  2999 QDomElement QDomNode::previousSiblingElement(const QString &tagName) const
       
  3000 {
       
  3001     for (QDomNode sib = previousSibling(); !sib.isNull(); sib = sib.previousSibling()) {
       
  3002         if (sib.isElement()) {
       
  3003             QDomElement elt = sib.toElement();
       
  3004             if (tagName.isEmpty() || elt.tagName() == tagName)
       
  3005                 return elt;
       
  3006         }
       
  3007     }
       
  3008     return QDomElement();
       
  3009 }
       
  3010 
       
  3011 /*!
       
  3012     \since 4.1
       
  3013 
       
  3014     For nodes created by QDomDocument::setContent(), this function
       
  3015     returns the line number in the XML document where the node was parsed.
       
  3016     Otherwise, -1 is returned.
       
  3017 
       
  3018     \sa columnNumber(), QDomDocument::setContent()
       
  3019 */
       
  3020 int QDomNode::lineNumber() const
       
  3021 {
       
  3022     return impl ? impl->lineNumber : -1;
       
  3023 }
       
  3024 
       
  3025 /*!
       
  3026     \since 4.1
       
  3027 
       
  3028     For nodes created by QDomDocument::setContent(), this function
       
  3029     returns the column number in the XML document where the node was parsed.
       
  3030     Otherwise, -1 is returned.
       
  3031 
       
  3032     \sa lineNumber(), QDomDocument::setContent()
       
  3033 */
       
  3034 int QDomNode::columnNumber() const
       
  3035 {
       
  3036     return impl ? impl->columnNumber : -1;
       
  3037 }
       
  3038 
       
  3039 
       
  3040 /**************************************************************
       
  3041  *
       
  3042  * QDomNamedNodeMapPrivate
       
  3043  *
       
  3044  **************************************************************/
       
  3045 
       
  3046 QDomNamedNodeMapPrivate::QDomNamedNodeMapPrivate(QDomNodePrivate* n)
       
  3047 {
       
  3048     ref = 1;
       
  3049     readonly = false;
       
  3050     parent = n;
       
  3051     appendToParent = false;
       
  3052 }
       
  3053 
       
  3054 QDomNamedNodeMapPrivate::~QDomNamedNodeMapPrivate()
       
  3055 {
       
  3056     clearMap();
       
  3057 }
       
  3058 
       
  3059 QDomNamedNodeMapPrivate* QDomNamedNodeMapPrivate::clone(QDomNodePrivate* p)
       
  3060 {
       
  3061     QScopedPointer<QDomNamedNodeMapPrivate> m(new QDomNamedNodeMapPrivate(p));
       
  3062     m->readonly = readonly;
       
  3063     m->appendToParent = appendToParent;
       
  3064 
       
  3065     QHash<QString, QDomNodePrivate*>::const_iterator it = map.constBegin();
       
  3066     for (; it != map.constEnd(); ++it) {
       
  3067         QDomNodePrivate *new_node = (*it)->cloneNode();
       
  3068         new_node->setParent(p);
       
  3069         m->setNamedItem(new_node);
       
  3070     }
       
  3071 
       
  3072     // we are no longer interested in ownership
       
  3073     m->ref.deref();
       
  3074     return m.take();
       
  3075 }
       
  3076 
       
  3077 void QDomNamedNodeMapPrivate::clearMap()
       
  3078 {
       
  3079     // Dereference all of our children if we took references
       
  3080     if (!appendToParent) {
       
  3081         QHash<QString, QDomNodePrivate *>::const_iterator it = map.constBegin();
       
  3082         for (; it != map.constEnd(); ++it)
       
  3083             if (!(*it)->ref.deref())
       
  3084                 delete *it;
       
  3085     }
       
  3086     map.clear();
       
  3087 }
       
  3088 
       
  3089 QDomNodePrivate* QDomNamedNodeMapPrivate::namedItem(const QString& name) const
       
  3090 {
       
  3091     QDomNodePrivate* p = map[name];
       
  3092     return p;
       
  3093 }
       
  3094 
       
  3095 QDomNodePrivate* QDomNamedNodeMapPrivate::namedItemNS(const QString& nsURI, const QString& localName) const
       
  3096 {
       
  3097     QHash<QString, QDomNodePrivate *>::const_iterator it = map.constBegin();
       
  3098     QDomNodePrivate *n;
       
  3099     for (; it != map.constEnd(); ++it) {
       
  3100         n = *it;
       
  3101         if (!n->prefix.isNull()) {
       
  3102             // node has a namespace
       
  3103             if (n->namespaceURI == nsURI && n->name == localName)
       
  3104                 return n;
       
  3105         }
       
  3106     }
       
  3107     return 0;
       
  3108 }
       
  3109 
       
  3110 QDomNodePrivate* QDomNamedNodeMapPrivate::setNamedItem(QDomNodePrivate* arg)
       
  3111 {
       
  3112     if (readonly || !arg)
       
  3113         return 0;
       
  3114 
       
  3115     if (appendToParent)
       
  3116         return parent->appendChild(arg);
       
  3117 
       
  3118     QDomNodePrivate *n = map.value(arg->nodeName());
       
  3119     // We take a reference
       
  3120     arg->ref.ref();
       
  3121     map.insertMulti(arg->nodeName(), arg);
       
  3122     return n;
       
  3123 }
       
  3124 
       
  3125 QDomNodePrivate* QDomNamedNodeMapPrivate::setNamedItemNS(QDomNodePrivate* arg)
       
  3126 {
       
  3127     if (readonly || !arg)
       
  3128         return 0;
       
  3129 
       
  3130     if (appendToParent)
       
  3131         return parent->appendChild(arg);
       
  3132 
       
  3133     if (!arg->prefix.isNull()) {
       
  3134         // node has a namespace
       
  3135         QDomNodePrivate *n = namedItemNS(arg->namespaceURI, arg->name);
       
  3136         // We take a reference
       
  3137         arg->ref.ref();
       
  3138         map.insertMulti(arg->nodeName(), arg);
       
  3139         return n;
       
  3140     } else {
       
  3141         // ### check the following code if it is ok
       
  3142         return setNamedItem(arg);
       
  3143     }
       
  3144 }
       
  3145 
       
  3146 QDomNodePrivate* QDomNamedNodeMapPrivate::removeNamedItem(const QString& name)
       
  3147 {
       
  3148     if (readonly)
       
  3149         return 0;
       
  3150 
       
  3151     QDomNodePrivate* p = namedItem(name);
       
  3152     if (p == 0)
       
  3153         return 0;
       
  3154     if (appendToParent)
       
  3155         return parent->removeChild(p);
       
  3156 
       
  3157     map.remove(p->nodeName());
       
  3158     // We took a reference, so we have to free one here
       
  3159     p->ref.deref();
       
  3160     return p;
       
  3161 }
       
  3162 
       
  3163 QDomNodePrivate* QDomNamedNodeMapPrivate::item(int index) const
       
  3164 {
       
  3165     if ((uint)index >= length())
       
  3166         return 0;
       
  3167     return *(map.constBegin() + index);
       
  3168 }
       
  3169 
       
  3170 // ### Qt 5: convert all length/size() functions in QDom to use int instead of uint.
       
  3171 uint QDomNamedNodeMapPrivate::length() const
       
  3172 {
       
  3173     return map.count();
       
  3174 }
       
  3175 
       
  3176 bool QDomNamedNodeMapPrivate::contains(const QString& name) const
       
  3177 {
       
  3178     return map.value(name) != 0;
       
  3179 }
       
  3180 
       
  3181 bool QDomNamedNodeMapPrivate::containsNS(const QString& nsURI, const QString & localName) const
       
  3182 {
       
  3183     return namedItemNS(nsURI, localName) != 0;
       
  3184 }
       
  3185 
       
  3186 /**************************************************************
       
  3187  *
       
  3188  * QDomNamedNodeMap
       
  3189  *
       
  3190  **************************************************************/
       
  3191 
       
  3192 #define IMPL ((QDomNamedNodeMapPrivate*)impl)
       
  3193 
       
  3194 /*!
       
  3195     \class QDomNamedNodeMap
       
  3196     \reentrant
       
  3197     \brief The QDomNamedNodeMap class contains a collection of nodes
       
  3198     that can be accessed by name.
       
  3199 
       
  3200     \inmodule QtXml
       
  3201     \ingroup xml-tools
       
  3202 
       
  3203     Note that QDomNamedNodeMap does not inherit from QDomNodeList.
       
  3204     QDomNamedNodeMaps do not provide any specific node ordering.
       
  3205     Although nodes in a QDomNamedNodeMap may be accessed by an ordinal
       
  3206     index, this is simply to allow a convenient enumeration of the
       
  3207     contents of a QDomNamedNodeMap, and does not imply that the DOM
       
  3208     specifies an ordering of the nodes.
       
  3209 
       
  3210     The QDomNamedNodeMap is used in three places:
       
  3211     \list 1
       
  3212     \i QDomDocumentType::entities() returns a map of all entities
       
  3213         described in the DTD.
       
  3214     \i QDomDocumentType::notations() returns a map of all notations
       
  3215         described in the DTD.
       
  3216     \i QDomNode::attributes() returns a map of all attributes of an
       
  3217         element.
       
  3218     \endlist
       
  3219 
       
  3220     Items in the map are identified by the name which QDomNode::name()
       
  3221     returns. Nodes are retrieved using namedItem(), namedItemNS() or
       
  3222     item(). New nodes are inserted with setNamedItem() or
       
  3223     setNamedItemNS() and removed with removeNamedItem() or
       
  3224     removeNamedItemNS(). Use contains() to see if an item with the
       
  3225     given name is in the named node map. The number of items is
       
  3226     returned by length().
       
  3227 
       
  3228     Terminology: in this class we use "item" and "node"
       
  3229     interchangeably.
       
  3230 */
       
  3231 
       
  3232 /*!
       
  3233     Constructs an empty named node map.
       
  3234 */
       
  3235 QDomNamedNodeMap::QDomNamedNodeMap()
       
  3236 {
       
  3237     impl = 0;
       
  3238 }
       
  3239 
       
  3240 /*!
       
  3241     Constructs a copy of \a n.
       
  3242 */
       
  3243 QDomNamedNodeMap::QDomNamedNodeMap(const QDomNamedNodeMap &n)
       
  3244 {
       
  3245     impl = n.impl;
       
  3246     if (impl)
       
  3247         impl->ref.ref();
       
  3248 }
       
  3249 
       
  3250 QDomNamedNodeMap::QDomNamedNodeMap(QDomNamedNodeMapPrivate *n)
       
  3251 {
       
  3252     impl = n;
       
  3253     if (impl)
       
  3254         impl->ref.ref();
       
  3255 }
       
  3256 
       
  3257 /*!
       
  3258     Assigns \a n to this named node map.
       
  3259 */
       
  3260 QDomNamedNodeMap& QDomNamedNodeMap::operator=(const QDomNamedNodeMap &n)
       
  3261 {
       
  3262     if (n.impl)
       
  3263         n.impl->ref.ref();
       
  3264     if (impl && !impl->ref.deref())
       
  3265         delete impl;
       
  3266     impl = n.impl;
       
  3267     return *this;
       
  3268 }
       
  3269 
       
  3270 /*!
       
  3271     Returns true if \a n and this named node map are equal; otherwise
       
  3272     returns false.
       
  3273 */
       
  3274 bool QDomNamedNodeMap::operator== (const QDomNamedNodeMap& n) const
       
  3275 {
       
  3276     return (impl == n.impl);
       
  3277 }
       
  3278 
       
  3279 /*!
       
  3280     Returns true if \a n and this named node map are not equal;
       
  3281     otherwise returns false.
       
  3282 */
       
  3283 bool QDomNamedNodeMap::operator!= (const QDomNamedNodeMap& n) const
       
  3284 {
       
  3285     return (impl != n.impl);
       
  3286 }
       
  3287 
       
  3288 /*!
       
  3289     Destroys the object and frees its resources.
       
  3290 */
       
  3291 QDomNamedNodeMap::~QDomNamedNodeMap()
       
  3292 {
       
  3293     if (impl && !impl->ref.deref())
       
  3294         delete impl;
       
  3295 }
       
  3296 
       
  3297 /*!
       
  3298     Returns the node called \a name.
       
  3299 
       
  3300     If the named node map does not contain such a node, a \link
       
  3301     QDomNode::isNull() null node\endlink is returned. A node's name is
       
  3302     the name returned by QDomNode::nodeName().
       
  3303 
       
  3304     \sa setNamedItem() namedItemNS()
       
  3305 */
       
  3306 QDomNode QDomNamedNodeMap::namedItem(const QString& name) const
       
  3307 {
       
  3308     if (!impl)
       
  3309         return QDomNode();
       
  3310     return QDomNode(IMPL->namedItem(name));
       
  3311 }
       
  3312 
       
  3313 /*!
       
  3314     Inserts the node \a newNode into the named node map. The name used
       
  3315     by the map is the node name of \a newNode as returned by
       
  3316     QDomNode::nodeName().
       
  3317 
       
  3318     If the new node replaces an existing node, i.e. the map contains a
       
  3319     node with the same name, the replaced node is returned.
       
  3320 
       
  3321     \sa namedItem() removeNamedItem() setNamedItemNS()
       
  3322 */
       
  3323 QDomNode QDomNamedNodeMap::setNamedItem(const QDomNode& newNode)
       
  3324 {
       
  3325     if (!impl)
       
  3326         return QDomNode();
       
  3327     return QDomNode(IMPL->setNamedItem((QDomNodePrivate*)newNode.impl));
       
  3328 }
       
  3329 
       
  3330 /*!
       
  3331     Removes the node called \a name from the map.
       
  3332 
       
  3333     The function returns the removed node or a \link
       
  3334     QDomNode::isNull() null node\endlink if the map did not contain a
       
  3335     node called \a name.
       
  3336 
       
  3337     \sa setNamedItem() namedItem() removeNamedItemNS()
       
  3338 */
       
  3339 QDomNode QDomNamedNodeMap::removeNamedItem(const QString& name)
       
  3340 {
       
  3341     if (!impl)
       
  3342         return QDomNode();
       
  3343     return QDomNode(IMPL->removeNamedItem(name));
       
  3344 }
       
  3345 
       
  3346 /*!
       
  3347     Retrieves the node at position \a index.
       
  3348 
       
  3349     This can be used to iterate over the map. Note that the nodes in
       
  3350     the map are ordered arbitrarily.
       
  3351 
       
  3352     \sa length()
       
  3353 */
       
  3354 QDomNode QDomNamedNodeMap::item(int index) const
       
  3355 {
       
  3356     if (!impl)
       
  3357         return QDomNode();
       
  3358     return QDomNode(IMPL->item(index));
       
  3359 }
       
  3360 
       
  3361 /*!
       
  3362     Returns the node associated with the local name \a localName and
       
  3363     the namespace URI \a nsURI.
       
  3364 
       
  3365     If the map does not contain such a node, a \link
       
  3366     QDomNode::isNull() null node\endlink is returned.
       
  3367 
       
  3368     \sa setNamedItemNS() namedItem()
       
  3369 */
       
  3370 QDomNode QDomNamedNodeMap::namedItemNS(const QString& nsURI, const QString& localName) const
       
  3371 {
       
  3372     if (!impl)
       
  3373         return QDomNode();
       
  3374     return QDomNode(IMPL->namedItemNS(nsURI, localName));
       
  3375 }
       
  3376 
       
  3377 /*!
       
  3378     Inserts the node \a newNode in the map. If a node with the same
       
  3379     namespace URI and the same local name already exists in the map,
       
  3380     it is replaced by \a newNode. If the new node replaces an existing
       
  3381     node, the replaced node is returned.
       
  3382 
       
  3383     \sa namedItemNS() removeNamedItemNS() setNamedItem()
       
  3384 */
       
  3385 QDomNode QDomNamedNodeMap::setNamedItemNS(const QDomNode& newNode)
       
  3386 {
       
  3387     if (!impl)
       
  3388         return QDomNode();
       
  3389     return QDomNode(IMPL->setNamedItemNS((QDomNodePrivate*)newNode.impl));
       
  3390 }
       
  3391 
       
  3392 /*!
       
  3393     Removes the node with the local name \a localName and the
       
  3394     namespace URI \a nsURI from the map.
       
  3395 
       
  3396     The function returns the removed node or a \link
       
  3397     QDomNode::isNull() null node\endlink if the map did not contain a
       
  3398     node with the local name \a localName and the namespace URI \a
       
  3399     nsURI.
       
  3400 
       
  3401     \sa setNamedItemNS() namedItemNS() removeNamedItem()
       
  3402 */
       
  3403 QDomNode QDomNamedNodeMap::removeNamedItemNS(const QString& nsURI, const QString& localName)
       
  3404 {
       
  3405     if (!impl)
       
  3406         return QDomNode();
       
  3407     QDomNodePrivate *n = IMPL->namedItemNS(nsURI, localName);
       
  3408     if (!n)
       
  3409         return QDomNode();
       
  3410     return QDomNode(IMPL->removeNamedItem(n->name));
       
  3411 }
       
  3412 
       
  3413 /*!
       
  3414     Returns the number of nodes in the map.
       
  3415 
       
  3416     \sa item()
       
  3417 */
       
  3418 uint QDomNamedNodeMap::length() const
       
  3419 {
       
  3420     if (!impl)
       
  3421         return 0;
       
  3422     return IMPL->length();
       
  3423 }
       
  3424 
       
  3425 /*!
       
  3426     \fn bool QDomNamedNodeMap::isEmpty() const
       
  3427 
       
  3428     Returns true if the map is empty; otherwise returns false. This function is
       
  3429     provided for Qt API consistency.
       
  3430 */
       
  3431 
       
  3432 /*!
       
  3433     \fn int QDomNamedNodeMap::count() const
       
  3434 
       
  3435     This function is provided for Qt API consistency. It is equivalent to length().
       
  3436 */
       
  3437 
       
  3438 /*!
       
  3439     \fn int QDomNamedNodeMap::size() const
       
  3440 
       
  3441     This function is provided for Qt API consistency. It is equivalent to length().
       
  3442 */
       
  3443 
       
  3444 /*!
       
  3445     Returns true if the map contains a node called \a name; otherwise
       
  3446     returns false.
       
  3447 
       
  3448     \bold{Note:} This function does not take the presence of namespaces into account.
       
  3449     Use namedItemNS() to test whether the map contains a node with a specific namespace
       
  3450     URI and name.
       
  3451 */
       
  3452 bool QDomNamedNodeMap::contains(const QString& name) const
       
  3453 {
       
  3454     if (!impl)
       
  3455         return false;
       
  3456     return IMPL->contains(name);
       
  3457 }
       
  3458 
       
  3459 #undef IMPL
       
  3460 
       
  3461 /**************************************************************
       
  3462  *
       
  3463  * QDomDocumentTypePrivate
       
  3464  *
       
  3465  **************************************************************/
       
  3466 
       
  3467 QDomDocumentTypePrivate::QDomDocumentTypePrivate(QDomDocumentPrivate* doc, QDomNodePrivate* parent)
       
  3468     : QDomNodePrivate(doc, parent)
       
  3469 {
       
  3470     init();
       
  3471 }
       
  3472 
       
  3473 QDomDocumentTypePrivate::QDomDocumentTypePrivate(QDomDocumentTypePrivate* n, bool deep)
       
  3474     : QDomNodePrivate(n, deep)
       
  3475 {
       
  3476     init();
       
  3477     // Refill the maps with our new children
       
  3478     QDomNodePrivate* p = first;
       
  3479     while (p) {
       
  3480         if (p->isEntity())
       
  3481             // Dont use normal insert function since we would create infinite recursion
       
  3482             entities->map.insertMulti(p->nodeName(), p);
       
  3483         if (p->isNotation())
       
  3484             // Dont use normal insert function since we would create infinite recursion
       
  3485             notations->map.insertMulti(p->nodeName(), p);
       
  3486     }
       
  3487 }
       
  3488 
       
  3489 QDomDocumentTypePrivate::~QDomDocumentTypePrivate()
       
  3490 {
       
  3491     if (!entities->ref.deref())
       
  3492         delete entities;
       
  3493     if (!notations->ref.deref())
       
  3494         delete notations;
       
  3495 }
       
  3496 
       
  3497 void QDomDocumentTypePrivate::init()
       
  3498 {
       
  3499     entities = new QDomNamedNodeMapPrivate(this);
       
  3500     QT_TRY {
       
  3501         notations = new QDomNamedNodeMapPrivate(this);
       
  3502         publicId.clear();
       
  3503         systemId.clear();
       
  3504         internalSubset.clear();
       
  3505 
       
  3506         entities->setAppendToParent(true);
       
  3507         notations->setAppendToParent(true);
       
  3508     } QT_CATCH(...) {
       
  3509         delete entities;
       
  3510         QT_RETHROW;
       
  3511     }
       
  3512 }
       
  3513 
       
  3514 QDomNodePrivate* QDomDocumentTypePrivate::cloneNode(bool deep)
       
  3515 {
       
  3516     QDomNodePrivate* p = new QDomDocumentTypePrivate(this, deep);
       
  3517     // We are not interested in this node
       
  3518     p->ref.deref();
       
  3519     return p;
       
  3520 }
       
  3521 
       
  3522 QDomNodePrivate* QDomDocumentTypePrivate::insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild)
       
  3523 {
       
  3524     // Call the origianl implementation
       
  3525     QDomNodePrivate* p = QDomNodePrivate::insertBefore(newChild, refChild);
       
  3526     // Update the maps
       
  3527     if (p && p->isEntity())
       
  3528         entities->map.insertMulti(p->nodeName(), p);
       
  3529     else if (p && p->isNotation())
       
  3530         notations->map.insertMulti(p->nodeName(), p);
       
  3531 
       
  3532     return p;
       
  3533 }
       
  3534 
       
  3535 QDomNodePrivate* QDomDocumentTypePrivate::insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild)
       
  3536 {
       
  3537     // Call the origianl implementation
       
  3538     QDomNodePrivate* p = QDomNodePrivate::insertAfter(newChild, refChild);
       
  3539     // Update the maps
       
  3540     if (p && p->isEntity())
       
  3541         entities->map.insertMulti(p->nodeName(), p);
       
  3542     else if (p && p->isNotation())
       
  3543         notations->map.insertMulti(p->nodeName(), p);
       
  3544 
       
  3545     return p;
       
  3546 }
       
  3547 
       
  3548 QDomNodePrivate* QDomDocumentTypePrivate::replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild)
       
  3549 {
       
  3550     // Call the origianl implementation
       
  3551     QDomNodePrivate* p = QDomNodePrivate::replaceChild(newChild, oldChild);
       
  3552     // Update the maps
       
  3553     if (p) {
       
  3554         if (oldChild && oldChild->isEntity())
       
  3555             entities->map.remove(oldChild->nodeName());
       
  3556         else if (oldChild && oldChild->isNotation())
       
  3557             notations->map.remove(oldChild->nodeName());
       
  3558 
       
  3559         if (p->isEntity())
       
  3560             entities->map.insertMulti(p->nodeName(), p);
       
  3561         else if (p->isNotation())
       
  3562             notations->map.insertMulti(p->nodeName(), p);
       
  3563     }
       
  3564 
       
  3565     return p;
       
  3566 }
       
  3567 
       
  3568 QDomNodePrivate* QDomDocumentTypePrivate::removeChild(QDomNodePrivate* oldChild)
       
  3569 {
       
  3570     // Call the origianl implementation
       
  3571     QDomNodePrivate* p = QDomNodePrivate::removeChild( oldChild);
       
  3572     // Update the maps
       
  3573     if (p && p->isEntity())
       
  3574         entities->map.remove(p->nodeName());
       
  3575     else if (p && p->isNotation())
       
  3576         notations->map.remove(p ->nodeName());
       
  3577 
       
  3578     return p;
       
  3579 }
       
  3580 
       
  3581 QDomNodePrivate* QDomDocumentTypePrivate::appendChild(QDomNodePrivate* newChild)
       
  3582 {
       
  3583     return insertAfter(newChild, 0);
       
  3584 }
       
  3585 
       
  3586 static QString quotedValue(const QString &data)
       
  3587 {
       
  3588     QChar quote = data.indexOf(QLatin1Char('\'')) == -1
       
  3589                     ? QLatin1Char('\'')
       
  3590                     : QLatin1Char('"');
       
  3591     return quote + data + quote;
       
  3592 }
       
  3593 
       
  3594 void QDomDocumentTypePrivate::save(QTextStream& s, int, int indent) const
       
  3595 {
       
  3596     if (name.isEmpty())
       
  3597         return;
       
  3598 
       
  3599     s << "<!DOCTYPE " << name;
       
  3600 
       
  3601     if (!publicId.isNull()) {
       
  3602         s << " PUBLIC " << quotedValue(publicId);
       
  3603         if (!systemId.isNull()) {
       
  3604             s << ' ' << quotedValue(systemId);
       
  3605         }
       
  3606     } else if (!systemId.isNull()) {
       
  3607         s << " SYSTEM " << quotedValue(systemId);
       
  3608     }
       
  3609 
       
  3610     if (entities->length()>0 || notations->length()>0) {
       
  3611         s << " [" << endl;
       
  3612 
       
  3613         QHash<QString, QDomNodePrivate *>::const_iterator it2 = notations->map.constBegin();
       
  3614         for (; it2 != notations->map.constEnd(); ++it2)
       
  3615             (*it2)->save(s, 0, indent);
       
  3616 
       
  3617         QHash<QString, QDomNodePrivate *>::const_iterator it = entities->map.constBegin();
       
  3618         for (; it != entities->map.constEnd(); ++it)
       
  3619             (*it)->save(s, 0, indent);
       
  3620 
       
  3621         s << ']';
       
  3622     }
       
  3623 
       
  3624     s << '>' << endl;
       
  3625 }
       
  3626 
       
  3627 /**************************************************************
       
  3628  *
       
  3629  * QDomDocumentType
       
  3630  *
       
  3631  **************************************************************/
       
  3632 
       
  3633 #define IMPL ((QDomDocumentTypePrivate*)impl)
       
  3634 
       
  3635 /*!
       
  3636     \class QDomDocumentType
       
  3637     \reentrant
       
  3638     \brief The QDomDocumentType class is the representation of the DTD
       
  3639     in the document tree.
       
  3640 
       
  3641     \inmodule QtXml
       
  3642     \ingroup xml-tools
       
  3643 
       
  3644     The QDomDocumentType class allows read-only access to some of the
       
  3645     data structures in the DTD: it can return a map of all entities()
       
  3646     and notations(). In addition the function name() returns the name
       
  3647     of the document type as specified in the &lt;!DOCTYPE name&gt;
       
  3648     tag. This class also provides the publicId(), systemId() and
       
  3649     internalSubset() functions.
       
  3650 
       
  3651     \sa QDomDocument
       
  3652 */
       
  3653 
       
  3654 /*!
       
  3655     Creates an empty QDomDocumentType object.
       
  3656 */
       
  3657 QDomDocumentType::QDomDocumentType() : QDomNode()
       
  3658 {
       
  3659 }
       
  3660 
       
  3661 /*!
       
  3662     Constructs a copy of \a n.
       
  3663 
       
  3664     The data of the copy is shared (shallow copy): modifying one node
       
  3665     will also change the other. If you want to make a deep copy, use
       
  3666     cloneNode().
       
  3667 */
       
  3668 QDomDocumentType::QDomDocumentType(const QDomDocumentType& n)
       
  3669     : QDomNode(n)
       
  3670 {
       
  3671 }
       
  3672 
       
  3673 QDomDocumentType::QDomDocumentType(QDomDocumentTypePrivate* n)
       
  3674     : QDomNode(n)
       
  3675 {
       
  3676 }
       
  3677 
       
  3678 /*!
       
  3679     Assigns \a n to this document type.
       
  3680 
       
  3681     The data of the copy is shared (shallow copy): modifying one node
       
  3682     will also change the other. If you want to make a deep copy, use
       
  3683     cloneNode().
       
  3684 */
       
  3685 QDomDocumentType& QDomDocumentType::operator= (const QDomDocumentType& n)
       
  3686 {
       
  3687     return (QDomDocumentType&) QDomNode::operator=(n);
       
  3688 }
       
  3689 
       
  3690 /*!
       
  3691     Returns the name of the document type as specified in the
       
  3692     &lt;!DOCTYPE name&gt; tag.
       
  3693 
       
  3694     \sa nodeName()
       
  3695 */
       
  3696 QString QDomDocumentType::name() const
       
  3697 {
       
  3698     if (!impl)
       
  3699         return QString();
       
  3700     return IMPL->nodeName();
       
  3701 }
       
  3702 
       
  3703 /*!
       
  3704     Returns a map of all entities described in the DTD.
       
  3705 */
       
  3706 QDomNamedNodeMap QDomDocumentType::entities() const
       
  3707 {
       
  3708     if (!impl)
       
  3709         return QDomNamedNodeMap();
       
  3710     return QDomNamedNodeMap(IMPL->entities);
       
  3711 }
       
  3712 
       
  3713 /*!
       
  3714     Returns a map of all notations described in the DTD.
       
  3715 */
       
  3716 QDomNamedNodeMap QDomDocumentType::notations() const
       
  3717 {
       
  3718     if (!impl)
       
  3719         return QDomNamedNodeMap();
       
  3720     return QDomNamedNodeMap(IMPL->notations);
       
  3721 }
       
  3722 
       
  3723 /*!
       
  3724     Returns the public identifier of the external DTD subset or
       
  3725     an empty string if there is no public identifier.
       
  3726 
       
  3727     \sa systemId() internalSubset() QDomImplementation::createDocumentType()
       
  3728 */
       
  3729 QString QDomDocumentType::publicId() const
       
  3730 {
       
  3731     if (!impl)
       
  3732         return QString();
       
  3733     return IMPL->publicId;
       
  3734 }
       
  3735 
       
  3736 /*!
       
  3737     Returns the system identifier of the external DTD subset or
       
  3738     an empty string if there is no system identifier.
       
  3739 
       
  3740     \sa publicId() internalSubset() QDomImplementation::createDocumentType()
       
  3741 */
       
  3742 QString QDomDocumentType::systemId() const
       
  3743 {
       
  3744     if (!impl)
       
  3745         return QString();
       
  3746     return IMPL->systemId;
       
  3747 }
       
  3748 
       
  3749 /*!
       
  3750     Returns the internal subset of the document type or an empty
       
  3751     string if there is no internal subset.
       
  3752 
       
  3753     \sa publicId() systemId()
       
  3754 */
       
  3755 QString QDomDocumentType::internalSubset() const
       
  3756 {
       
  3757     if (!impl)
       
  3758         return QString();
       
  3759     return IMPL->internalSubset;
       
  3760 }
       
  3761 
       
  3762 /*
       
  3763     Are these needed at all? The only difference when removing these
       
  3764     two methods in all subclasses is that we'd get a different type
       
  3765     for null nodes.
       
  3766 */
       
  3767 
       
  3768 /*!
       
  3769     \fn QDomNode::NodeType QDomDocumentType::nodeType() const
       
  3770 
       
  3771     Returns \c DocumentTypeNode.
       
  3772 
       
  3773     \sa isDocumentType() QDomNode::toDocumentType()
       
  3774 */
       
  3775 
       
  3776 #undef IMPL
       
  3777 
       
  3778 /**************************************************************
       
  3779  *
       
  3780  * QDomDocumentFragmentPrivate
       
  3781  *
       
  3782  **************************************************************/
       
  3783 
       
  3784 QDomDocumentFragmentPrivate::QDomDocumentFragmentPrivate(QDomDocumentPrivate* doc, QDomNodePrivate* parent)
       
  3785     : QDomNodePrivate(doc, parent)
       
  3786 {
       
  3787     name = QLatin1String("#document-fragment");
       
  3788 }
       
  3789 
       
  3790 QDomDocumentFragmentPrivate::QDomDocumentFragmentPrivate(QDomNodePrivate* n, bool deep)
       
  3791     : QDomNodePrivate(n, deep)
       
  3792 {
       
  3793 }
       
  3794 
       
  3795 QDomNodePrivate* QDomDocumentFragmentPrivate::cloneNode(bool deep)
       
  3796 {
       
  3797     QDomNodePrivate* p = new QDomDocumentFragmentPrivate(this, deep);
       
  3798     // We are not interested in this node
       
  3799     p->ref.deref();
       
  3800     return p;
       
  3801 }
       
  3802 
       
  3803 /**************************************************************
       
  3804  *
       
  3805  * QDomDocumentFragment
       
  3806  *
       
  3807  **************************************************************/
       
  3808 
       
  3809 /*!
       
  3810     \class QDomDocumentFragment
       
  3811     \reentrant
       
  3812     \brief The QDomDocumentFragment class is a tree of QDomNodes which is not usually a complete QDomDocument.
       
  3813 
       
  3814     \inmodule QtXml
       
  3815     \ingroup xml-tools
       
  3816 
       
  3817     If you want to do complex tree operations it is useful to have a
       
  3818     lightweight class to store nodes and their relations.
       
  3819     QDomDocumentFragment stores a subtree of a document which does not
       
  3820     necessarily represent a well-formed XML document.
       
  3821 
       
  3822     QDomDocumentFragment is also useful if you want to group several
       
  3823     nodes in a list and insert them all together as children of some
       
  3824     node. In these cases QDomDocumentFragment can be used as a
       
  3825     temporary container for this list of children.
       
  3826 
       
  3827     The most important feature of QDomDocumentFragment is that it is
       
  3828     treated in a special way by QDomNode::insertAfter(),
       
  3829     QDomNode::insertBefore(), QDomNode::replaceChild() and
       
  3830     QDomNode::appendChild(): instead of inserting the fragment itself, all
       
  3831     the fragment's children are inserted.
       
  3832 */
       
  3833 
       
  3834 /*!
       
  3835     Constructs an empty document fragment.
       
  3836 */
       
  3837 QDomDocumentFragment::QDomDocumentFragment()
       
  3838 {
       
  3839 }
       
  3840 
       
  3841 QDomDocumentFragment::QDomDocumentFragment(QDomDocumentFragmentPrivate* n)
       
  3842     : QDomNode(n)
       
  3843 {
       
  3844 }
       
  3845 
       
  3846 /*!
       
  3847     Constructs a copy of \a x.
       
  3848 
       
  3849     The data of the copy is shared (shallow copy): modifying one node
       
  3850     will also change the other. If you want to make a deep copy, use
       
  3851     cloneNode().
       
  3852 */
       
  3853 QDomDocumentFragment::QDomDocumentFragment(const QDomDocumentFragment& x)
       
  3854     : QDomNode(x)
       
  3855 {
       
  3856 }
       
  3857 
       
  3858 /*!
       
  3859     Assigns \a x to this DOM document fragment.
       
  3860 
       
  3861     The data of the copy is shared (shallow copy): modifying one node
       
  3862     will also change the other. If you want to make a deep copy, use
       
  3863     cloneNode().
       
  3864 */
       
  3865 QDomDocumentFragment& QDomDocumentFragment::operator= (const QDomDocumentFragment& x)
       
  3866 {
       
  3867     return (QDomDocumentFragment&) QDomNode::operator=(x);
       
  3868 }
       
  3869 
       
  3870 /*!
       
  3871     \fn QDomNode::NodeType QDomDocumentFragment::nodeType() const
       
  3872 
       
  3873     Returns \c DocumentFragment.
       
  3874 
       
  3875     \sa isDocumentFragment() QDomNode::toDocumentFragment()
       
  3876 */
       
  3877 
       
  3878 /**************************************************************
       
  3879  *
       
  3880  * QDomCharacterDataPrivate
       
  3881  *
       
  3882  **************************************************************/
       
  3883 
       
  3884 QDomCharacterDataPrivate::QDomCharacterDataPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p,
       
  3885                                                       const QString& data)
       
  3886     : QDomNodePrivate(d, p)
       
  3887 {
       
  3888     value = data;
       
  3889     name = QLatin1String("#character-data");
       
  3890 }
       
  3891 
       
  3892 QDomCharacterDataPrivate::QDomCharacterDataPrivate(QDomCharacterDataPrivate* n, bool deep)
       
  3893     : QDomNodePrivate(n, deep)
       
  3894 {
       
  3895 }
       
  3896 
       
  3897 QDomNodePrivate* QDomCharacterDataPrivate::cloneNode(bool deep)
       
  3898 {
       
  3899     QDomNodePrivate* p = new QDomCharacterDataPrivate(this, deep);
       
  3900     // We are not interested in this node
       
  3901     p->ref.deref();
       
  3902     return p;
       
  3903 }
       
  3904 
       
  3905 uint QDomCharacterDataPrivate::dataLength() const
       
  3906 {
       
  3907     return value.length();
       
  3908 }
       
  3909 
       
  3910 QString QDomCharacterDataPrivate::substringData(unsigned long offset, unsigned long n) const
       
  3911 {
       
  3912     return value.mid(offset, n);
       
  3913 }
       
  3914 
       
  3915 void QDomCharacterDataPrivate::insertData(unsigned long offset, const QString& arg)
       
  3916 {
       
  3917     value.insert(offset, arg);
       
  3918 }
       
  3919 
       
  3920 void QDomCharacterDataPrivate::deleteData(unsigned long offset, unsigned long n)
       
  3921 {
       
  3922     value.remove(offset, n);
       
  3923 }
       
  3924 
       
  3925 void QDomCharacterDataPrivate::replaceData(unsigned long offset, unsigned long n, const QString& arg)
       
  3926 {
       
  3927     value.replace(offset, n, arg);
       
  3928 }
       
  3929 
       
  3930 void QDomCharacterDataPrivate::appendData(const QString& arg)
       
  3931 {
       
  3932     value += arg;
       
  3933 }
       
  3934 
       
  3935 /**************************************************************
       
  3936  *
       
  3937  * QDomCharacterData
       
  3938  *
       
  3939  **************************************************************/
       
  3940 
       
  3941 #define IMPL ((QDomCharacterDataPrivate*)impl)
       
  3942 
       
  3943 /*!
       
  3944     \class QDomCharacterData
       
  3945     \reentrant
       
  3946     \brief The QDomCharacterData class represents a generic string in the DOM.
       
  3947 
       
  3948     \inmodule QtXml
       
  3949     \ingroup xml-tools
       
  3950 
       
  3951     Character data as used in XML specifies a generic data string.
       
  3952     More specialized versions of this class are QDomText, QDomComment
       
  3953     and QDomCDATASection.
       
  3954 
       
  3955     The data string is set with setData() and retrieved with data().
       
  3956     You can retrieve a portion of the data string using
       
  3957     substringData(). Extra data can be appended with appendData(), or
       
  3958     inserted with insertData(). Portions of the data string can be
       
  3959     deleted with deleteData() or replaced with replaceData(). The
       
  3960     length of the data string is returned by length().
       
  3961 
       
  3962     The node type of the node containing this character data is
       
  3963     returned by nodeType().
       
  3964 
       
  3965     \sa QDomText QDomComment QDomCDATASection
       
  3966 */
       
  3967 
       
  3968 /*!
       
  3969     Constructs an empty character data object.
       
  3970 */
       
  3971 QDomCharacterData::QDomCharacterData()
       
  3972 {
       
  3973 }
       
  3974 
       
  3975 /*!
       
  3976     Constructs a copy of \a x.
       
  3977 
       
  3978     The data of the copy is shared (shallow copy): modifying one node
       
  3979     will also change the other. If you want to make a deep copy, use
       
  3980     cloneNode().
       
  3981 */
       
  3982 QDomCharacterData::QDomCharacterData(const QDomCharacterData& x)
       
  3983     : QDomNode(x)
       
  3984 {
       
  3985 }
       
  3986 
       
  3987 QDomCharacterData::QDomCharacterData(QDomCharacterDataPrivate* n)
       
  3988     : QDomNode(n)
       
  3989 {
       
  3990 }
       
  3991 
       
  3992 /*!
       
  3993     Assigns \a x to this character data.
       
  3994 
       
  3995     The data of the copy is shared (shallow copy): modifying one node
       
  3996     will also change the other. If you want to make a deep copy, use
       
  3997     cloneNode().
       
  3998 */
       
  3999 QDomCharacterData& QDomCharacterData::operator= (const QDomCharacterData& x)
       
  4000 {
       
  4001     return (QDomCharacterData&) QDomNode::operator=(x);
       
  4002 }
       
  4003 
       
  4004 /*!
       
  4005     Returns the string stored in this object.
       
  4006 
       
  4007     If the node is a \link isNull() null node\endlink, it will return
       
  4008     an empty string.
       
  4009 */
       
  4010 QString QDomCharacterData::data() const
       
  4011 {
       
  4012     if (!impl)
       
  4013         return QString();
       
  4014     return impl->nodeValue();
       
  4015 }
       
  4016 
       
  4017 /*!
       
  4018     Sets this object's string to \a v.
       
  4019 */
       
  4020 void QDomCharacterData::setData(const QString& v)
       
  4021 {
       
  4022     if (impl)
       
  4023         impl->setNodeValue(v);
       
  4024 }
       
  4025 
       
  4026 /*!
       
  4027     Returns the length of the stored string.
       
  4028 */
       
  4029 uint QDomCharacterData::length() const
       
  4030 {
       
  4031     if (impl)
       
  4032         return IMPL->dataLength();
       
  4033     return 0;
       
  4034 }
       
  4035 
       
  4036 /*!
       
  4037     Returns the substring of length \a count from position \a offset.
       
  4038 */
       
  4039 QString QDomCharacterData::substringData(unsigned long offset, unsigned long count)
       
  4040 {
       
  4041     if (!impl)
       
  4042         return QString();
       
  4043     return IMPL->substringData(offset, count);
       
  4044 }
       
  4045 
       
  4046 /*!
       
  4047     Appends the string \a arg to the stored string.
       
  4048 */
       
  4049 void QDomCharacterData::appendData(const QString& arg)
       
  4050 {
       
  4051     if (impl)
       
  4052         IMPL->appendData(arg);
       
  4053 }
       
  4054 
       
  4055 /*!
       
  4056     Inserts the string \a arg into the stored string at position \a offset.
       
  4057 */
       
  4058 void QDomCharacterData::insertData(unsigned long offset, const QString& arg)
       
  4059 {
       
  4060     if (impl)
       
  4061         IMPL->insertData(offset, arg);
       
  4062 }
       
  4063 
       
  4064 /*!
       
  4065     Deletes a substring of length \a count from position \a offset.
       
  4066 */
       
  4067 void QDomCharacterData::deleteData(unsigned long offset, unsigned long count)
       
  4068 {
       
  4069     if (impl)
       
  4070         IMPL->deleteData(offset, count);
       
  4071 }
       
  4072 
       
  4073 /*!
       
  4074     Replaces the substring of length \a count starting at position \a
       
  4075     offset with the string \a arg.
       
  4076 */
       
  4077 void QDomCharacterData::replaceData(unsigned long offset, unsigned long count, const QString& arg)
       
  4078 {
       
  4079     if (impl)
       
  4080         IMPL->replaceData(offset, count, arg);
       
  4081 }
       
  4082 
       
  4083 /*!
       
  4084     Returns the type of node this object refers to (i.e. \c TextNode,
       
  4085     \c CDATASectionNode, \c CommentNode or \c CharacterDataNode). For
       
  4086     a \link isNull() null node\endlink, returns \c CharacterDataNode.
       
  4087 */
       
  4088 QDomNode::NodeType QDomCharacterData::nodeType() const
       
  4089 {
       
  4090     if (!impl)
       
  4091         return CharacterDataNode;
       
  4092     return QDomNode::nodeType();
       
  4093 }
       
  4094 
       
  4095 #undef IMPL
       
  4096 
       
  4097 /**************************************************************
       
  4098  *
       
  4099  * QDomAttrPrivate
       
  4100  *
       
  4101  **************************************************************/
       
  4102 
       
  4103 QDomAttrPrivate::QDomAttrPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& name_)
       
  4104     : QDomNodePrivate(d, parent)
       
  4105 {
       
  4106     name = name_;
       
  4107     m_specified = false;
       
  4108 }
       
  4109 
       
  4110 QDomAttrPrivate::QDomAttrPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p, const QString& nsURI, const QString& qName)
       
  4111     : QDomNodePrivate(d, p)
       
  4112 {
       
  4113     qt_split_namespace(prefix, name, qName, !nsURI.isNull());
       
  4114     namespaceURI = nsURI;
       
  4115     createdWithDom1Interface = false;
       
  4116     m_specified = false;
       
  4117 }
       
  4118 
       
  4119 QDomAttrPrivate::QDomAttrPrivate(QDomAttrPrivate* n, bool deep)
       
  4120     : QDomNodePrivate(n, deep)
       
  4121 {
       
  4122     m_specified = n->specified();
       
  4123 }
       
  4124 
       
  4125 void QDomAttrPrivate::setNodeValue(const QString& v)
       
  4126 {
       
  4127     value = v;
       
  4128     QDomTextPrivate *t = new QDomTextPrivate(0, this, v);
       
  4129     // keep the refcount balanced: appendChild() does a ref anyway.
       
  4130     t->ref.deref();
       
  4131     if (first) {
       
  4132         delete removeChild(first);
       
  4133     }
       
  4134     appendChild(t);
       
  4135 }
       
  4136 
       
  4137 QDomNodePrivate* QDomAttrPrivate::cloneNode(bool deep)
       
  4138 {
       
  4139     QDomNodePrivate* p = new QDomAttrPrivate(this, deep);
       
  4140     // We are not interested in this node
       
  4141     p->ref.deref();
       
  4142     return p;
       
  4143 }
       
  4144 
       
  4145 bool QDomAttrPrivate::specified() const
       
  4146 {
       
  4147     return m_specified;
       
  4148 }
       
  4149 
       
  4150 /* \internal
       
  4151   Encode & escape \a str. Yes, it makes no sense to return a QString,
       
  4152   but is so for legacy reasons.
       
  4153 
       
  4154   Remember that content produced should be able to roundtrip with 2.11 End-of-Line Handling
       
  4155   and 3.3.3 Attribute-Value Normalization.
       
  4156 
       
  4157   If \a performAVN is true, characters will be escaped to survive Attribute Value Normalization.
       
  4158   If \a encodeEOLs is true, characters will be escaped to survive End-of-Line Handling.
       
  4159 */
       
  4160 static QString encodeText(const QString &str,
       
  4161                           QTextStream &s,
       
  4162                           const bool encodeQuotes = true,
       
  4163                           const bool performAVN = false,
       
  4164                           const bool encodeEOLs = false)
       
  4165 {
       
  4166 #ifdef QT_NO_TEXTCODEC
       
  4167     Q_UNUSED(s);
       
  4168 #else
       
  4169     const QTextCodec *const codec = s.codec();
       
  4170     Q_ASSERT(codec);
       
  4171 #endif
       
  4172     QString retval(str);
       
  4173     int len = retval.length();
       
  4174     int i = 0;
       
  4175 
       
  4176     while (i < len) {
       
  4177         const QChar ati(retval.at(i));
       
  4178 
       
  4179         if (ati == QLatin1Char('<')) {
       
  4180             retval.replace(i, 1, QLatin1String("&lt;"));
       
  4181             len += 3;
       
  4182             i += 4;
       
  4183         } else if (encodeQuotes && (ati == QLatin1Char('"'))) {
       
  4184             retval.replace(i, 1, QLatin1String("&quot;"));
       
  4185             len += 5;
       
  4186             i += 6;
       
  4187         } else if (ati == QLatin1Char('&')) {
       
  4188             retval.replace(i, 1, QLatin1String("&amp;"));
       
  4189             len += 4;
       
  4190             i += 5;
       
  4191         } else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']')) {
       
  4192             retval.replace(i, 1, QLatin1String("&gt;"));
       
  4193             len += 3;
       
  4194             i += 4;
       
  4195         } else if (performAVN &&
       
  4196                    (ati == QChar(0xA) ||
       
  4197                     ati == QChar(0xD) ||
       
  4198                     ati == QChar(0x9))) {
       
  4199             const QString replacement(QLatin1String("&#x") + QString::number(ati.unicode(), 16) + QLatin1Char(';'));
       
  4200             retval.replace(i, 1, replacement);
       
  4201             i += replacement.length();
       
  4202             len += replacement.length() - 1;
       
  4203         } else if (encodeEOLs && ati == QChar(0xD)) {
       
  4204             retval.replace(i, 1, QLatin1String("&#xd;")); // Replace a single 0xD with a ref for 0xD
       
  4205             len += 4;
       
  4206             i += 5;
       
  4207         } else {
       
  4208 #ifndef QT_NO_TEXTCODEC
       
  4209             if(codec->canEncode(ati))
       
  4210                 ++i;
       
  4211             else
       
  4212 #endif
       
  4213             {
       
  4214                 // We have to use a character reference to get it through.
       
  4215                 const ushort codepoint(ati.unicode());
       
  4216                 const QString replacement(QLatin1String("&#x") + QString::number(codepoint, 16) + QLatin1Char(';'));
       
  4217                 retval.replace(i, 1, replacement);
       
  4218                 i += replacement.length();
       
  4219                 len += replacement.length() - 1;
       
  4220             }
       
  4221         }
       
  4222     }
       
  4223 
       
  4224     return retval;
       
  4225 }
       
  4226 
       
  4227 void QDomAttrPrivate::save(QTextStream& s, int, int) const
       
  4228 {
       
  4229     if (namespaceURI.isNull()) {
       
  4230         s << name << "=\"" << encodeText(value, s, true, true) << '\"';
       
  4231     } else {
       
  4232         s << prefix << ':' << name << "=\"" << encodeText(value, s, true, true) << '\"';
       
  4233         /* This is a fix for 138243, as good as it gets.
       
  4234          *
       
  4235          * QDomElementPrivate::save() output a namespace declaration if
       
  4236          * the element is in a namespace, no matter what. This function do as well, meaning
       
  4237          * that we get two identical namespace declaration if we don't have the if-
       
  4238          * statement below.
       
  4239          *
       
  4240          * This doesn't work when the parent element has the same prefix as us but
       
  4241          * a different namespace. However, this can only occur by the user modifying the element,
       
  4242          * and we don't do fixups by that anyway, and hence it's the user responsibility to not
       
  4243          * arrive in those situations. */
       
  4244         if(!ownerNode ||
       
  4245            ownerNode->prefix != prefix) {
       
  4246             s << " xmlns:" << prefix << "=\"" << encodeText(namespaceURI, s, true, true) << '\"';
       
  4247         }
       
  4248     }
       
  4249 }
       
  4250 
       
  4251 /**************************************************************
       
  4252  *
       
  4253  * QDomAttr
       
  4254  *
       
  4255  **************************************************************/
       
  4256 
       
  4257 #define IMPL ((QDomAttrPrivate*)impl)
       
  4258 
       
  4259 /*!
       
  4260     \class QDomAttr
       
  4261     \reentrant
       
  4262     \brief The QDomAttr class represents one attribute of a QDomElement.
       
  4263 
       
  4264     \inmodule QtXml
       
  4265     \ingroup xml-tools
       
  4266 
       
  4267     For example, the following piece of XML produces an element with
       
  4268     no children, but two attributes:
       
  4269 
       
  4270     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 7
       
  4271 
       
  4272     You can access the attributes of an element with code like this:
       
  4273 
       
  4274     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 8
       
  4275 
       
  4276     This example also shows that changing an attribute received from
       
  4277     an element changes the attribute of the element. If you do not
       
  4278     want to change the value of the element's attribute you must
       
  4279     use cloneNode() to get an independent copy of the attribute.
       
  4280 
       
  4281     QDomAttr can return the name() and value() of an attribute. An
       
  4282     attribute's value is set with setValue(). If specified() returns
       
  4283     true the value was set with setValue(). The node this
       
  4284     attribute is attached to (if any) is returned by ownerElement().
       
  4285 
       
  4286     For further information about the Document Object Model see
       
  4287     \l{http://www.w3.org/TR/REC-DOM-Level-1/} and
       
  4288     \l{http://www.w3.org/TR/DOM-Level-2-Core/}.
       
  4289     For a more general introduction of the DOM implementation see the
       
  4290     QDomDocument documentation.
       
  4291 */
       
  4292 
       
  4293 
       
  4294 /*!
       
  4295     Constructs an empty attribute.
       
  4296 */
       
  4297 QDomAttr::QDomAttr()
       
  4298 {
       
  4299 }
       
  4300 
       
  4301 /*!
       
  4302     Constructs a copy of \a x.
       
  4303 
       
  4304     The data of the copy is shared (shallow copy): modifying one node
       
  4305     will also change the other. If you want to make a deep copy, use
       
  4306     cloneNode().
       
  4307 */
       
  4308 QDomAttr::QDomAttr(const QDomAttr& x)
       
  4309     : QDomNode(x)
       
  4310 {
       
  4311 }
       
  4312 
       
  4313 QDomAttr::QDomAttr(QDomAttrPrivate* n)
       
  4314     : QDomNode(n)
       
  4315 {
       
  4316 }
       
  4317 
       
  4318 /*!
       
  4319     Assigns \a x to this DOM attribute.
       
  4320 
       
  4321     The data of the copy is shared (shallow copy): modifying one node
       
  4322     will also change the other. If you want to make a deep copy, use
       
  4323     cloneNode().
       
  4324 */
       
  4325 QDomAttr& QDomAttr::operator= (const QDomAttr& x)
       
  4326 {
       
  4327     return (QDomAttr&) QDomNode::operator=(x);
       
  4328 }
       
  4329 
       
  4330 /*!
       
  4331     Returns the attribute's name.
       
  4332 */
       
  4333 QString QDomAttr::name() const
       
  4334 {
       
  4335     if (!impl)
       
  4336         return QString();
       
  4337     return impl->nodeName();
       
  4338 }
       
  4339 
       
  4340 /*!
       
  4341     Returns true if the attribute has been set by the user with setValue().
       
  4342     Returns false if the value hasn't been specified or set.
       
  4343 
       
  4344     \sa setValue()
       
  4345 */
       
  4346 bool QDomAttr::specified() const
       
  4347 {
       
  4348     if (!impl)
       
  4349         return false;
       
  4350     return IMPL->specified();
       
  4351 }
       
  4352 
       
  4353 /*!
       
  4354     Returns the element node this attribute is attached to or a \link
       
  4355     QDomNode::isNull() null node\endlink if this attribute is not
       
  4356     attached to any element.
       
  4357 */
       
  4358 QDomElement QDomAttr::ownerElement() const
       
  4359 {
       
  4360     Q_ASSERT(impl->parent());
       
  4361     if (!impl->parent()->isElement())
       
  4362         return QDomElement();
       
  4363     return QDomElement((QDomElementPrivate*)(impl->parent()));
       
  4364 }
       
  4365 
       
  4366 /*!
       
  4367     Returns the value of the attribute or an empty string if the
       
  4368     attribute has not been specified.
       
  4369 
       
  4370     \sa specified() setValue()
       
  4371 */
       
  4372 QString QDomAttr::value() const
       
  4373 {
       
  4374     if (!impl)
       
  4375         return QString();
       
  4376     return impl->nodeValue();
       
  4377 }
       
  4378 
       
  4379 /*!
       
  4380     Sets the attribute's value to \a v.
       
  4381 
       
  4382     \sa value()
       
  4383 */
       
  4384 void QDomAttr::setValue(const QString& v)
       
  4385 {
       
  4386     if (!impl)
       
  4387         return;
       
  4388     impl->setNodeValue(v);
       
  4389     IMPL->m_specified = true;
       
  4390 }
       
  4391 
       
  4392 /*!
       
  4393     \fn QDomNode::NodeType QDomAttr::nodeType() const
       
  4394 
       
  4395     Returns \link QDomNode::NodeType AttributeNode\endlink.
       
  4396 */
       
  4397 
       
  4398 #undef IMPL
       
  4399 
       
  4400 /**************************************************************
       
  4401  *
       
  4402  * QDomElementPrivate
       
  4403  *
       
  4404  **************************************************************/
       
  4405 
       
  4406 QDomElementPrivate::QDomElementPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p,
       
  4407                                           const QString& tagname)
       
  4408     : QDomNodePrivate(d, p)
       
  4409 {
       
  4410     name = tagname;
       
  4411     m_attr = new QDomNamedNodeMapPrivate(this);
       
  4412 }
       
  4413 
       
  4414 QDomElementPrivate::QDomElementPrivate(QDomDocumentPrivate* d, QDomNodePrivate* p,
       
  4415         const QString& nsURI, const QString& qName)
       
  4416     : QDomNodePrivate(d, p)
       
  4417 {
       
  4418     qt_split_namespace(prefix, name, qName, !nsURI.isNull());
       
  4419     namespaceURI = nsURI;
       
  4420     createdWithDom1Interface = false;
       
  4421     m_attr = new QDomNamedNodeMapPrivate(this);
       
  4422 }
       
  4423 
       
  4424 QDomElementPrivate::QDomElementPrivate(QDomElementPrivate* n, bool deep) :
       
  4425     QDomNodePrivate(n, deep)
       
  4426 {
       
  4427     m_attr = n->m_attr->clone(this);
       
  4428     // Reference is down to 0, so we set it to 1 here.
       
  4429     m_attr->ref.ref();
       
  4430 }
       
  4431 
       
  4432 QDomElementPrivate::~QDomElementPrivate()
       
  4433 {
       
  4434     if (!m_attr->ref.deref())
       
  4435         delete m_attr;
       
  4436 }
       
  4437 
       
  4438 QDomNodePrivate* QDomElementPrivate::cloneNode(bool deep)
       
  4439 {
       
  4440     QDomNodePrivate* p = new QDomElementPrivate(this, deep);
       
  4441     // We are not interested in this node
       
  4442     p->ref.deref();
       
  4443     return p;
       
  4444 }
       
  4445 
       
  4446 QString QDomElementPrivate::attribute(const QString& name_, const QString& defValue) const
       
  4447 {
       
  4448     QDomNodePrivate* n = m_attr->namedItem(name_);
       
  4449     if (!n)
       
  4450         return defValue;
       
  4451 
       
  4452     return n->nodeValue();
       
  4453 }
       
  4454 
       
  4455 QString QDomElementPrivate::attributeNS(const QString& nsURI, const QString& localName, const QString& defValue) const
       
  4456 {
       
  4457     QDomNodePrivate* n = m_attr->namedItemNS(nsURI, localName);
       
  4458     if (!n)
       
  4459         return defValue;
       
  4460 
       
  4461     return n->nodeValue();
       
  4462 }
       
  4463 
       
  4464 void QDomElementPrivate::setAttribute(const QString& aname, const QString& newValue)
       
  4465 {
       
  4466     QDomNodePrivate* n = m_attr->namedItem(aname);
       
  4467     if (!n) {
       
  4468         n = new QDomAttrPrivate(ownerDocument(), this, aname);
       
  4469         n->setNodeValue(newValue);
       
  4470 
       
  4471         // Referencing is done by the map, so we set the reference counter back
       
  4472         // to 0 here. This is ok since we created the QDomAttrPrivate.
       
  4473         n->ref.deref();
       
  4474         m_attr->setNamedItem(n);
       
  4475     } else {
       
  4476         n->setNodeValue(newValue);
       
  4477     }
       
  4478 }
       
  4479 
       
  4480 void QDomElementPrivate::setAttributeNS(const QString& nsURI, const QString& qName, const QString& newValue)
       
  4481 {
       
  4482     QString prefix, localName;
       
  4483     qt_split_namespace(prefix, localName, qName, true);
       
  4484     QDomNodePrivate* n = m_attr->namedItemNS(nsURI, localName);
       
  4485     if (!n) {
       
  4486         n = new QDomAttrPrivate(ownerDocument(), this, nsURI, qName);
       
  4487         n->setNodeValue(newValue);
       
  4488 
       
  4489         // Referencing is done by the map, so we set the reference counter back
       
  4490         // to 0 here. This is ok since we created the QDomAttrPrivate.
       
  4491         n->ref.deref();
       
  4492         m_attr->setNamedItem(n);
       
  4493     } else {
       
  4494         n->setNodeValue(newValue);
       
  4495         n->prefix = prefix;
       
  4496     }
       
  4497 }
       
  4498 
       
  4499 void QDomElementPrivate::removeAttribute(const QString& aname)
       
  4500 {
       
  4501     QDomNodePrivate* p = m_attr->removeNamedItem(aname);
       
  4502     if (p && p->ref == 0)
       
  4503         delete p;
       
  4504 }
       
  4505 
       
  4506 QDomAttrPrivate* QDomElementPrivate::attributeNode(const QString& aname)
       
  4507 {
       
  4508     return (QDomAttrPrivate*)m_attr->namedItem(aname);
       
  4509 }
       
  4510 
       
  4511 QDomAttrPrivate* QDomElementPrivate::attributeNodeNS(const QString& nsURI, const QString& localName)
       
  4512 {
       
  4513     return (QDomAttrPrivate*)m_attr->namedItemNS(nsURI, localName);
       
  4514 }
       
  4515 
       
  4516 QDomAttrPrivate* QDomElementPrivate::setAttributeNode(QDomAttrPrivate* newAttr)
       
  4517 {
       
  4518     QDomNodePrivate* n = m_attr->namedItem(newAttr->nodeName());
       
  4519 
       
  4520     // Referencing is done by the maps
       
  4521     m_attr->setNamedItem(newAttr);
       
  4522 
       
  4523     newAttr->setParent(this);
       
  4524 
       
  4525     return (QDomAttrPrivate*)n;
       
  4526 }
       
  4527 
       
  4528 QDomAttrPrivate* QDomElementPrivate::setAttributeNodeNS(QDomAttrPrivate* newAttr)
       
  4529 {
       
  4530     QDomNodePrivate* n = 0;
       
  4531     if (!newAttr->prefix.isNull())
       
  4532         n = m_attr->namedItemNS(newAttr->namespaceURI, newAttr->name);
       
  4533 
       
  4534     // Referencing is done by the maps
       
  4535     m_attr->setNamedItem(newAttr);
       
  4536 
       
  4537     return (QDomAttrPrivate*)n;
       
  4538 }
       
  4539 
       
  4540 QDomAttrPrivate* QDomElementPrivate::removeAttributeNode(QDomAttrPrivate* oldAttr)
       
  4541 {
       
  4542     return (QDomAttrPrivate*)m_attr->removeNamedItem(oldAttr->nodeName());
       
  4543 }
       
  4544 
       
  4545 bool QDomElementPrivate::hasAttribute(const QString& aname)
       
  4546 {
       
  4547     return m_attr->contains(aname);
       
  4548 }
       
  4549 
       
  4550 bool QDomElementPrivate::hasAttributeNS(const QString& nsURI, const QString& localName)
       
  4551 {
       
  4552     return m_attr->containsNS(nsURI, localName);
       
  4553 }
       
  4554 
       
  4555 QString QDomElementPrivate::text()
       
  4556 {
       
  4557     QString t(QLatin1String(""));
       
  4558 
       
  4559     QDomNodePrivate* p = first;
       
  4560     while (p) {
       
  4561         if (p->isText() || p->isCDATASection())
       
  4562             t += p->nodeValue();
       
  4563         else if (p->isElement())
       
  4564             t += ((QDomElementPrivate*)p)->text();
       
  4565         p = p->next;
       
  4566     }
       
  4567 
       
  4568     return t;
       
  4569 }
       
  4570 
       
  4571 void QDomElementPrivate::save(QTextStream& s, int depth, int indent) const
       
  4572 {
       
  4573     if (!(prev && prev->isText()))
       
  4574         s << QString(indent < 1 ? 0 : depth * indent, QLatin1Char(' '));
       
  4575 
       
  4576     QString qName(name);
       
  4577     QString nsDecl(QLatin1String(""));
       
  4578     if (!namespaceURI.isNull()) {
       
  4579         /** ### Qt 5:
       
  4580          *
       
  4581          * If we still have QDom, optimize this so that we only declare namespaces that are not
       
  4582          * yet declared. We loose default namespace mappings, so maybe we should rather store
       
  4583          * the information that we get from startPrefixMapping()/endPrefixMapping() and use them.
       
  4584          * Modifications becomes more complex then, however.
       
  4585          *
       
  4586          * We cannot do this during the Qt 4 series because it would require too invasive changes, and
       
  4587          * hence possibly behavioral changes.
       
  4588          */
       
  4589         if (prefix.isEmpty()) {
       
  4590             nsDecl = QLatin1String(" xmlns");
       
  4591         } else {
       
  4592             qName = prefix + QLatin1Char(':') + name;
       
  4593             nsDecl = QLatin1String(" xmlns:") + prefix;
       
  4594         }
       
  4595         nsDecl += QLatin1String("=\"") + encodeText(namespaceURI, s) + QLatin1Char('\"');
       
  4596     }
       
  4597     s << '<' << qName << nsDecl;
       
  4598 
       
  4599     QSet<QString> outputtedPrefixes;
       
  4600 
       
  4601     /* Write out attributes. */
       
  4602     if (!m_attr->map.isEmpty()) {
       
  4603         QHash<QString, QDomNodePrivate *>::const_iterator it = m_attr->map.constBegin();
       
  4604         for (; it != m_attr->map.constEnd(); ++it) {
       
  4605             s << ' ';
       
  4606             if (it.value()->namespaceURI.isNull()) {
       
  4607                 s << it.value()->name << "=\"" << encodeText(it.value()->value, s, true, true) << '\"';
       
  4608             } else {
       
  4609                 s << it.value()->prefix << ':' << it.value()->name << "=\"" << encodeText(it.value()->value, s, true, true) << '\"';
       
  4610                 /* This is a fix for 138243, as good as it gets.
       
  4611                  *
       
  4612                  * QDomElementPrivate::save() output a namespace declaration if
       
  4613                  * the element is in a namespace, no matter what. This function do as well, meaning
       
  4614                  * that we get two identical namespace declaration if we don't have the if-
       
  4615                  * statement below.
       
  4616                  *
       
  4617                  * This doesn't work when the parent element has the same prefix as us but
       
  4618                  * a different namespace. However, this can only occur by the user modifying the element,
       
  4619                  * and we don't do fixups by that anyway, and hence it's the user responsibility to not
       
  4620                  * arrive in those situations. */
       
  4621                 if((!it.value()->ownerNode ||
       
  4622                    it.value()->ownerNode->prefix != it.value()->prefix) &&
       
  4623                    !outputtedPrefixes.contains(it.value()->prefix)) {
       
  4624                     s << " xmlns:" << it.value()->prefix << "=\"" << encodeText(it.value()->namespaceURI, s, true, true) << '\"';
       
  4625                     outputtedPrefixes.insert(it.value()->prefix);
       
  4626                 }
       
  4627             }
       
  4628         }
       
  4629     }
       
  4630 
       
  4631     if (last) {
       
  4632         // has child nodes
       
  4633         if (first->isText())
       
  4634             s << '>';
       
  4635         else {
       
  4636             s << '>';
       
  4637 
       
  4638             /* -1 disables new lines. */
       
  4639             if (indent != -1)
       
  4640                 s << endl;
       
  4641         }
       
  4642         QDomNodePrivate::save(s, depth + 1, indent); if (!last->isText())
       
  4643             s << QString(indent < 1 ? 0 : depth * indent, QLatin1Char(' '));
       
  4644 
       
  4645         s << "</" << qName << '>';
       
  4646     } else {
       
  4647         s << "/>";
       
  4648     }
       
  4649     if (!(next && next->isText())) {
       
  4650         /* -1 disables new lines. */
       
  4651         if (indent != -1)
       
  4652             s << endl;
       
  4653     }
       
  4654 }
       
  4655 
       
  4656 /**************************************************************
       
  4657  *
       
  4658  * QDomElement
       
  4659  *
       
  4660  **************************************************************/
       
  4661 
       
  4662 #define IMPL ((QDomElementPrivate*)impl)
       
  4663 
       
  4664 /*!
       
  4665     \class QDomElement
       
  4666     \reentrant
       
  4667     \brief The QDomElement class represents one element in the DOM tree.
       
  4668 
       
  4669     \inmodule QtXml
       
  4670     \ingroup xml-tools
       
  4671 
       
  4672     Elements have a tagName() and zero or more attributes associated
       
  4673     with them. The tag name can be changed with setTagName().
       
  4674 
       
  4675     Element attributes are represented by QDomAttr objects that can
       
  4676     be queried using the attribute() and attributeNode() functions.
       
  4677     You can set attributes with the setAttribute() and
       
  4678     setAttributeNode() functions. Attributes can be removed with
       
  4679     removeAttribute(). There are namespace-aware equivalents to these
       
  4680     functions, i.e. setAttributeNS(), setAttributeNodeNS() and
       
  4681     removeAttributeNS().
       
  4682 
       
  4683     If you want to access the text of a node use text(), e.g.
       
  4684     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 9
       
  4685     The text() function operates recursively to find the text (since
       
  4686     not all elements contain text). If you want to find all the text
       
  4687     in all of a node's children, iterate over the children looking for
       
  4688     QDomText nodes, e.g.
       
  4689     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 10
       
  4690     Note that we attempt to convert each node to a text node and use
       
  4691     text() rather than using firstChild().toText().data() or
       
  4692     n.toText().data() directly on the node, because the node may not
       
  4693     be a text element.
       
  4694 
       
  4695     You can get a list of all the decendents of an element which have
       
  4696     a specified tag name with elementsByTagName() or
       
  4697     elementsByTagNameNS().
       
  4698 
       
  4699     To browse the elements of a dom document use firstChildElement(), lastChildElement(),
       
  4700     nextSiblingElement() and previousSiblingElement(). For example, to iterate over all
       
  4701     child elements called "entry" in a root element called "database", you can use:
       
  4702     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 11
       
  4703 
       
  4704     For further information about the Document Object Model see
       
  4705     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  4706     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  4707     For a more general introduction of the DOM implementation see the
       
  4708     QDomDocument documentation.
       
  4709 */
       
  4710 
       
  4711 /*!
       
  4712     Constructs an empty element. Use the QDomDocument::createElement()
       
  4713     function to construct elements with content.
       
  4714 */
       
  4715 QDomElement::QDomElement()
       
  4716     : QDomNode()
       
  4717 {
       
  4718 }
       
  4719 
       
  4720 /*!
       
  4721     Constructs a copy of \a x.
       
  4722 
       
  4723     The data of the copy is shared (shallow copy): modifying one node
       
  4724     will also change the other. If you want to make a deep copy, use
       
  4725     cloneNode().
       
  4726 */
       
  4727 QDomElement::QDomElement(const QDomElement& x)
       
  4728     : QDomNode(x)
       
  4729 {
       
  4730 }
       
  4731 
       
  4732 QDomElement::QDomElement(QDomElementPrivate* n)
       
  4733     : QDomNode(n)
       
  4734 {
       
  4735 }
       
  4736 
       
  4737 /*!
       
  4738     Assigns \a x to this DOM element.
       
  4739 
       
  4740     The data of the copy is shared (shallow copy): modifying one node
       
  4741     will also change the other. If you want to make a deep copy, use
       
  4742     cloneNode().
       
  4743 */
       
  4744 QDomElement& QDomElement::operator= (const QDomElement& x)
       
  4745 {
       
  4746     return (QDomElement&) QDomNode::operator=(x);
       
  4747 }
       
  4748 
       
  4749 /*!
       
  4750     \fn QDomNode::NodeType QDomElement::nodeType() const
       
  4751 
       
  4752     Returns \c ElementNode.
       
  4753 */
       
  4754 
       
  4755 /*!
       
  4756     Sets this element's tag name to \a name.
       
  4757 
       
  4758     \sa tagName()
       
  4759 */
       
  4760 void QDomElement::setTagName(const QString& name)
       
  4761 {
       
  4762     if (impl)
       
  4763         impl->name = name;
       
  4764 }
       
  4765 
       
  4766 /*!
       
  4767     Returns the tag name of this element. For an XML element like this:
       
  4768 
       
  4769     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 12
       
  4770 
       
  4771     the tagname would return "img".
       
  4772 
       
  4773     \sa setTagName()
       
  4774 */
       
  4775 QString QDomElement::tagName() const
       
  4776 {
       
  4777     if (!impl)
       
  4778         return QString();
       
  4779     return impl->nodeName();
       
  4780 }
       
  4781 
       
  4782 
       
  4783 /*!
       
  4784     Returns a QDomNamedNodeMap containing all this element's attributes.
       
  4785 
       
  4786     \sa attribute() setAttribute() attributeNode() setAttributeNode()
       
  4787 */
       
  4788 QDomNamedNodeMap QDomElement::attributes() const
       
  4789 {
       
  4790     if (!impl)
       
  4791         return QDomNamedNodeMap();
       
  4792     return QDomNamedNodeMap(IMPL->attributes());
       
  4793 }
       
  4794 
       
  4795 /*!
       
  4796     Returns the attribute called \a name. If the attribute does not
       
  4797     exist \a defValue is returned.
       
  4798 
       
  4799     \sa setAttribute() attributeNode() setAttributeNode() attributeNS()
       
  4800 */
       
  4801 QString QDomElement::attribute(const QString& name, const QString& defValue) const
       
  4802 {
       
  4803     if (!impl)
       
  4804         return defValue;
       
  4805     return IMPL->attribute(name, defValue);
       
  4806 }
       
  4807 
       
  4808 /*!
       
  4809     Adds an attribute called \a name with value \a value. If an
       
  4810     attribute with the same name exists, its value is replaced by \a
       
  4811     value.
       
  4812 
       
  4813     \sa attribute() setAttributeNode() setAttributeNS()
       
  4814 */
       
  4815 void QDomElement::setAttribute(const QString& name, const QString& value)
       
  4816 {
       
  4817     if (!impl)
       
  4818         return;
       
  4819     IMPL->setAttribute(name, value);
       
  4820 }
       
  4821 
       
  4822 /*!
       
  4823   \fn void QDomElement::setAttribute(const QString& name, int value)
       
  4824 
       
  4825     \overload
       
  4826     The number is formatted according to the current locale.
       
  4827 */
       
  4828 
       
  4829 /*!
       
  4830   \fn void QDomElement::setAttribute(const QString& name, uint value)
       
  4831 
       
  4832     \overload
       
  4833     The number is formatted according to the current locale.
       
  4834 */
       
  4835 
       
  4836 /*!
       
  4837     \overload
       
  4838 
       
  4839     The number is formatted according to the current locale.
       
  4840 */
       
  4841 void QDomElement::setAttribute(const QString& name, qlonglong value)
       
  4842 {
       
  4843     if (!impl)
       
  4844         return;
       
  4845     QString x;
       
  4846     x.setNum(value);
       
  4847     IMPL->setAttribute(name, x);
       
  4848 }
       
  4849 
       
  4850 /*!
       
  4851     \overload
       
  4852 
       
  4853     The number is formatted according to the current locale.
       
  4854 */
       
  4855 void QDomElement::setAttribute(const QString& name, qulonglong value)
       
  4856 {
       
  4857     if (!impl)
       
  4858         return;
       
  4859     QString x;
       
  4860     x.setNum(value);
       
  4861     IMPL->setAttribute(name, x);
       
  4862 }
       
  4863 
       
  4864 /*!
       
  4865     \overload
       
  4866 
       
  4867     The number is formatted according to the current locale.
       
  4868 */
       
  4869 void QDomElement::setAttribute(const QString& name, float value)
       
  4870 {
       
  4871     if (!impl)
       
  4872         return;
       
  4873     QString x;
       
  4874     x.setNum(value);
       
  4875     IMPL->setAttribute(name, x);
       
  4876 }
       
  4877 
       
  4878 /*!
       
  4879     \overload
       
  4880 
       
  4881     The number is formatted according to the current locale.
       
  4882 */
       
  4883 void QDomElement::setAttribute(const QString& name, double value)
       
  4884 {
       
  4885     if (!impl)
       
  4886         return;
       
  4887     QString x;
       
  4888     char buf[256];
       
  4889     int count = qsnprintf(buf, sizeof(buf), "%.16g", value);
       
  4890     if (count > 0)
       
  4891         x = QString::fromLatin1(buf, count);
       
  4892     else
       
  4893         x.setNum(value); // Fallback
       
  4894     IMPL->setAttribute(name, x);
       
  4895 }
       
  4896 
       
  4897 /*!
       
  4898     Removes the attribute called name \a name from this element.
       
  4899 
       
  4900     \sa setAttribute() attribute() removeAttributeNS()
       
  4901 */
       
  4902 void QDomElement::removeAttribute(const QString& name)
       
  4903 {
       
  4904     if (!impl)
       
  4905         return;
       
  4906     IMPL->removeAttribute(name);
       
  4907 }
       
  4908 
       
  4909 /*!
       
  4910     Returns the QDomAttr object that corresponds to the attribute
       
  4911     called \a name. If no such attribute exists a \link
       
  4912     QDomNode::isNull() null attribute\endlink is returned.
       
  4913 
       
  4914     \sa setAttributeNode() attribute() setAttribute() attributeNodeNS()
       
  4915 */
       
  4916 QDomAttr QDomElement::attributeNode(const QString& name)
       
  4917 {
       
  4918     if (!impl)
       
  4919         return QDomAttr();
       
  4920     return QDomAttr(IMPL->attributeNode(name));
       
  4921 }
       
  4922 
       
  4923 /*!
       
  4924     Adds the attribute \a newAttr to this element.
       
  4925 
       
  4926     If the element has another attribute that has the same name as \a
       
  4927     newAttr, this function replaces that attribute and returns it;
       
  4928     otherwise the function returns a \link QDomNode::isNull() null
       
  4929     attribute\endlink.
       
  4930 
       
  4931     \sa attributeNode() setAttribute() setAttributeNodeNS()
       
  4932 */
       
  4933 QDomAttr QDomElement::setAttributeNode(const QDomAttr& newAttr)
       
  4934 {
       
  4935     if (!impl)
       
  4936         return QDomAttr();
       
  4937     return QDomAttr(IMPL->setAttributeNode(((QDomAttrPrivate*)newAttr.impl)));
       
  4938 }
       
  4939 
       
  4940 /*!
       
  4941     Removes the attribute \a oldAttr from the element and returns it.
       
  4942 
       
  4943     \sa attributeNode() setAttributeNode()
       
  4944 */
       
  4945 QDomAttr QDomElement::removeAttributeNode(const QDomAttr& oldAttr)
       
  4946 {
       
  4947     if (!impl)
       
  4948         return QDomAttr(); // ### should this return oldAttr?
       
  4949     return QDomAttr(IMPL->removeAttributeNode(((QDomAttrPrivate*)oldAttr.impl)));
       
  4950 }
       
  4951 
       
  4952 /*!
       
  4953   Returns a QDomNodeList containing all descendants of this element
       
  4954   named \a tagname encountered during a preorder traversal of the
       
  4955   element subtree with this element as its root. The order of the
       
  4956   elements in the returned list is the order they are encountered
       
  4957   during the preorder traversal.
       
  4958 
       
  4959   \sa elementsByTagNameNS() QDomDocument::elementsByTagName()
       
  4960 */
       
  4961 QDomNodeList QDomElement::elementsByTagName(const QString& tagname) const
       
  4962 {
       
  4963     return QDomNodeList(new QDomNodeListPrivate(impl, tagname));
       
  4964 }
       
  4965 
       
  4966 /*!
       
  4967   Returns true if this element has an attribute called \a name;
       
  4968   otherwise returns false.
       
  4969 
       
  4970   \bold{Note:} This function does not take the presence of namespaces
       
  4971   into account.  As a result, the specified name will be tested
       
  4972   against fully-qualified attribute names that include any namespace
       
  4973   prefixes that may be present.
       
  4974 
       
  4975   Use hasAttributeNS() to explicitly test for attributes with specific
       
  4976   namespaces and names.
       
  4977 */
       
  4978 bool QDomElement::hasAttribute(const QString& name) const
       
  4979 {
       
  4980     if (!impl)
       
  4981         return false;
       
  4982     return IMPL->hasAttribute(name);
       
  4983 }
       
  4984 
       
  4985 /*!
       
  4986     Returns the attribute with the local name \a localName and the
       
  4987     namespace URI \a nsURI. If the attribute does not exist \a
       
  4988     defValue is returned.
       
  4989 
       
  4990     \sa setAttributeNS() attributeNodeNS() setAttributeNodeNS() attribute()
       
  4991 */
       
  4992 QString QDomElement::attributeNS(const QString nsURI, const QString& localName, const QString& defValue) const
       
  4993 {
       
  4994     if (!impl)
       
  4995         return defValue;
       
  4996     return IMPL->attributeNS(nsURI, localName, defValue);
       
  4997 }
       
  4998 
       
  4999 /*!
       
  5000     Adds an attribute with the qualified name \a qName and the
       
  5001     namespace URI \a nsURI with the value \a value. If an attribute
       
  5002     with the same local name and namespace URI exists, its prefix is
       
  5003     replaced by the prefix of \a qName and its value is repaced by \a
       
  5004     value.
       
  5005 
       
  5006     Although \a qName is the qualified name, the local name is used to
       
  5007     decide if an existing attribute's value should be replaced.
       
  5008 
       
  5009     \sa attributeNS() setAttributeNodeNS() setAttribute()
       
  5010 */
       
  5011 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, const QString& value)
       
  5012 {
       
  5013     if (!impl)
       
  5014         return;
       
  5015     IMPL->setAttributeNS(nsURI, qName, value);
       
  5016 }
       
  5017 
       
  5018 /*!
       
  5019   \fn void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, int value)
       
  5020 
       
  5021     \overload
       
  5022 */
       
  5023 
       
  5024 /*!
       
  5025   \fn void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, uint value)
       
  5026 
       
  5027     \overload
       
  5028 */
       
  5029 
       
  5030 /*!
       
  5031     \overload
       
  5032 */
       
  5033 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qlonglong value)
       
  5034 {
       
  5035     if (!impl)
       
  5036         return;
       
  5037     QString x;
       
  5038     x.setNum(value);
       
  5039     IMPL->setAttributeNS(nsURI, qName, x);
       
  5040 }
       
  5041 
       
  5042 /*!
       
  5043     \overload
       
  5044 */
       
  5045 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, qulonglong value)
       
  5046 {
       
  5047     if (!impl)
       
  5048         return;
       
  5049     QString x;
       
  5050     x.setNum(value);
       
  5051     IMPL->setAttributeNS(nsURI, qName, x);
       
  5052 }
       
  5053 
       
  5054 /*!
       
  5055     \overload
       
  5056 */
       
  5057 void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, double value)
       
  5058 {
       
  5059     if (!impl)
       
  5060         return;
       
  5061     QString x;
       
  5062     x.setNum(value);
       
  5063     IMPL->setAttributeNS(nsURI, qName, x);
       
  5064 }
       
  5065 
       
  5066 /*!
       
  5067     Removes the attribute with the local name \a localName and the
       
  5068     namespace URI \a nsURI from this element.
       
  5069 
       
  5070     \sa setAttributeNS() attributeNS() removeAttribute()
       
  5071 */
       
  5072 void QDomElement::removeAttributeNS(const QString& nsURI, const QString& localName)
       
  5073 {
       
  5074     if (!impl)
       
  5075         return;
       
  5076     QDomNodePrivate *n = IMPL->attributeNodeNS(nsURI, localName);
       
  5077     if (!n)
       
  5078         return;
       
  5079     IMPL->removeAttribute(n->nodeName());
       
  5080 }
       
  5081 
       
  5082 /*!
       
  5083     Returns the QDomAttr object that corresponds to the attribute
       
  5084     with the local name \a localName and the namespace URI \a nsURI.
       
  5085     If no such attribute exists a \l{QDomNode::isNull()}{null
       
  5086     attribute} is returned.
       
  5087 
       
  5088     \sa setAttributeNode() attribute() setAttribute()
       
  5089 */
       
  5090 QDomAttr QDomElement::attributeNodeNS(const QString& nsURI, const QString& localName)
       
  5091 {
       
  5092     if (!impl)
       
  5093         return QDomAttr();
       
  5094     return QDomAttr(IMPL->attributeNodeNS(nsURI, localName));
       
  5095 }
       
  5096 
       
  5097 /*!
       
  5098     Adds the attribute \a newAttr to this element.
       
  5099 
       
  5100     If the element has another attribute that has the same local name
       
  5101     and namespace URI as \a newAttr, this function replaces that
       
  5102     attribute and returns it; otherwise the function returns a \link
       
  5103     QDomNode::isNull() null attribute\endlink.
       
  5104 
       
  5105     \sa attributeNodeNS() setAttributeNS() setAttributeNode()
       
  5106 */
       
  5107 QDomAttr QDomElement::setAttributeNodeNS(const QDomAttr& newAttr)
       
  5108 {
       
  5109     if (!impl)
       
  5110         return QDomAttr();
       
  5111     return QDomAttr(IMPL->setAttributeNodeNS(((QDomAttrPrivate*)newAttr.impl)));
       
  5112 }
       
  5113 
       
  5114 /*!
       
  5115   Returns a QDomNodeList containing all descendants of this element
       
  5116   with local name \a localName and namespace URI \a nsURI encountered
       
  5117   during a preorder traversal of the element subtree with this element
       
  5118   as its root. The order of the elements in the returned list is the
       
  5119   order they are encountered during the preorder traversal.
       
  5120 
       
  5121   \sa elementsByTagName() QDomDocument::elementsByTagNameNS()
       
  5122 */
       
  5123 QDomNodeList QDomElement::elementsByTagNameNS(const QString& nsURI, const QString& localName) const
       
  5124 {
       
  5125     return QDomNodeList(new QDomNodeListPrivate(impl, nsURI, localName));
       
  5126 }
       
  5127 
       
  5128 /*!
       
  5129     Returns true if this element has an attribute with the local name
       
  5130     \a localName and the namespace URI \a nsURI; otherwise returns
       
  5131     false.
       
  5132 */
       
  5133 bool QDomElement::hasAttributeNS(const QString& nsURI, const QString& localName) const
       
  5134 {
       
  5135     if (!impl)
       
  5136         return false;
       
  5137     return IMPL->hasAttributeNS(nsURI, localName);
       
  5138 }
       
  5139 
       
  5140 /*!
       
  5141     Returns the element's text or an empty string.
       
  5142 
       
  5143     Example:
       
  5144     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 13
       
  5145 
       
  5146     The function text() of the QDomElement for the \c{<h1>} tag,
       
  5147     will return the following text:
       
  5148 
       
  5149     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 14
       
  5150 
       
  5151     Comments are ignored by this function. It only evaluates QDomText
       
  5152     and QDomCDATASection objects.
       
  5153 */
       
  5154 QString QDomElement::text() const
       
  5155 {
       
  5156     if (!impl)
       
  5157         return QString();
       
  5158     return IMPL->text();
       
  5159 }
       
  5160 
       
  5161 #undef IMPL
       
  5162 
       
  5163 /**************************************************************
       
  5164  *
       
  5165  * QDomTextPrivate
       
  5166  *
       
  5167  **************************************************************/
       
  5168 
       
  5169 QDomTextPrivate::QDomTextPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& val)
       
  5170     : QDomCharacterDataPrivate(d, parent, val)
       
  5171 {
       
  5172     name = QLatin1String("#text");
       
  5173 }
       
  5174 
       
  5175 QDomTextPrivate::QDomTextPrivate(QDomTextPrivate* n, bool deep)
       
  5176     : QDomCharacterDataPrivate(n, deep)
       
  5177 {
       
  5178 }
       
  5179 
       
  5180 QDomNodePrivate* QDomTextPrivate::cloneNode(bool deep)
       
  5181 {
       
  5182     QDomNodePrivate* p = new QDomTextPrivate(this, deep);
       
  5183     // We are not interested in this node
       
  5184     p->ref.deref();
       
  5185     return p;
       
  5186 }
       
  5187 
       
  5188 QDomTextPrivate* QDomTextPrivate::splitText(int offset)
       
  5189 {
       
  5190     if (!parent()) {
       
  5191         qWarning("QDomText::splitText  The node has no parent. So I can not split");
       
  5192         return 0;
       
  5193     }
       
  5194 
       
  5195     QDomTextPrivate* t = new QDomTextPrivate(ownerDocument(), 0, value.mid(offset));
       
  5196     value.truncate(offset);
       
  5197 
       
  5198     parent()->insertAfter(t, this);
       
  5199 
       
  5200     return t;
       
  5201 }
       
  5202 
       
  5203 void QDomTextPrivate::save(QTextStream& s, int, int) const
       
  5204 {
       
  5205     QDomTextPrivate *that = const_cast<QDomTextPrivate*>(this);
       
  5206     s << encodeText(value, s, !(that->parent() && that->parent()->isElement()), false, true);
       
  5207 }
       
  5208 
       
  5209 /**************************************************************
       
  5210  *
       
  5211  * QDomText
       
  5212  *
       
  5213  **************************************************************/
       
  5214 
       
  5215 #define IMPL ((QDomTextPrivate*)impl)
       
  5216 
       
  5217 /*!
       
  5218     \class QDomText
       
  5219     \reentrant
       
  5220     \brief The QDomText class represents text data in the parsed XML document.
       
  5221 
       
  5222     \inmodule QtXml
       
  5223     \ingroup xml-tools
       
  5224 
       
  5225     You can split the text in a QDomText object over two QDomText
       
  5226     objecs with splitText().
       
  5227 
       
  5228     For further information about the Document Object Model see
       
  5229     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5230     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5231     For a more general introduction of the DOM implementation see the
       
  5232     QDomDocument documentation.
       
  5233 */
       
  5234 
       
  5235 /*!
       
  5236     Constructs an empty QDomText object.
       
  5237 
       
  5238     To construct a QDomText with content, use QDomDocument::createTextNode().
       
  5239 */
       
  5240 QDomText::QDomText()
       
  5241     : QDomCharacterData()
       
  5242 {
       
  5243 }
       
  5244 
       
  5245 /*!
       
  5246     Constructs a copy of \a x.
       
  5247 
       
  5248     The data of the copy is shared (shallow copy): modifying one node
       
  5249     will also change the other. If you want to make a deep copy, use
       
  5250     cloneNode().
       
  5251 */
       
  5252 QDomText::QDomText(const QDomText& x)
       
  5253     : QDomCharacterData(x)
       
  5254 {
       
  5255 }
       
  5256 
       
  5257 QDomText::QDomText(QDomTextPrivate* n)
       
  5258     : QDomCharacterData(n)
       
  5259 {
       
  5260 }
       
  5261 
       
  5262 /*!
       
  5263     Assigns \a x to this DOM text.
       
  5264 
       
  5265     The data of the copy is shared (shallow copy): modifying one node
       
  5266     will also change the other. If you want to make a deep copy, use
       
  5267     cloneNode().
       
  5268 */
       
  5269 QDomText& QDomText::operator= (const QDomText& x)
       
  5270 {
       
  5271     return (QDomText&) QDomNode::operator=(x);
       
  5272 }
       
  5273 
       
  5274 /*!
       
  5275     \fn QDomNode::NodeType QDomText::nodeType() const
       
  5276 
       
  5277     Returns \c TextNode.
       
  5278 */
       
  5279 
       
  5280 /*!
       
  5281     Splits this DOM text object into two QDomText objects. This object
       
  5282     keeps its first \a offset characters and the second (newly
       
  5283     created) object is inserted into the document tree after this
       
  5284     object with the remaining characters.
       
  5285 
       
  5286     The function returns the newly created object.
       
  5287 
       
  5288     \sa QDomNode::normalize()
       
  5289 */
       
  5290 QDomText QDomText::splitText(int offset)
       
  5291 {
       
  5292     if (!impl)
       
  5293         return QDomText();
       
  5294     return QDomText(IMPL->splitText(offset));
       
  5295 }
       
  5296 
       
  5297 #undef IMPL
       
  5298 
       
  5299 /**************************************************************
       
  5300  *
       
  5301  * QDomCommentPrivate
       
  5302  *
       
  5303  **************************************************************/
       
  5304 
       
  5305 QDomCommentPrivate::QDomCommentPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& val)
       
  5306     : QDomCharacterDataPrivate(d, parent, val)
       
  5307 {
       
  5308     name = QLatin1String("#comment");
       
  5309 }
       
  5310 
       
  5311 QDomCommentPrivate::QDomCommentPrivate(QDomCommentPrivate* n, bool deep)
       
  5312     : QDomCharacterDataPrivate(n, deep)
       
  5313 {
       
  5314 }
       
  5315 
       
  5316 
       
  5317 QDomNodePrivate* QDomCommentPrivate::cloneNode(bool deep)
       
  5318 {
       
  5319     QDomNodePrivate* p = new QDomCommentPrivate(this, deep);
       
  5320     // We are not interested in this node
       
  5321     p->ref.deref();
       
  5322     return p;
       
  5323 }
       
  5324 
       
  5325 void QDomCommentPrivate::save(QTextStream& s, int depth, int indent) const
       
  5326 {
       
  5327     /* We don't output whitespace if we would pollute a text node. */
       
  5328     if (!(prev && prev->isText()))
       
  5329         s << QString(indent < 1 ? 0 : depth * indent, QLatin1Char(' '));
       
  5330 
       
  5331     s << "<!--" << value;
       
  5332     if (value.endsWith(QLatin1Char('-')))
       
  5333         s << ' '; // Ensures that XML comment doesn't end with --->
       
  5334     s << "-->";
       
  5335 
       
  5336     if (!(next && next->isText()))
       
  5337         s << endl;
       
  5338 }
       
  5339 
       
  5340 /**************************************************************
       
  5341  *
       
  5342  * QDomComment
       
  5343  *
       
  5344  **************************************************************/
       
  5345 
       
  5346 /*!
       
  5347     \class QDomComment
       
  5348     \reentrant
       
  5349     \brief The QDomComment class represents an XML comment.
       
  5350 
       
  5351     \inmodule QtXml
       
  5352     \ingroup xml-tools
       
  5353 
       
  5354     A comment in the parsed XML such as this:
       
  5355     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 15
       
  5356     is represented by QDomComment objects in the parsed Dom tree.
       
  5357 
       
  5358     For further information about the Document Object Model see
       
  5359     \l{http://www.w3.org/TR/REC-DOM-Level-1/} and
       
  5360     \l{http://www.w3.org/TR/DOM-Level-2-Core/}.
       
  5361     For a more general introduction of the DOM implementation see the
       
  5362     QDomDocument documentation.
       
  5363 */
       
  5364 
       
  5365 /*!
       
  5366     Constructs an empty comment. To construct a comment with content,
       
  5367     use the QDomDocument::createComment() function.
       
  5368 */
       
  5369 QDomComment::QDomComment()
       
  5370     : QDomCharacterData()
       
  5371 {
       
  5372 }
       
  5373 
       
  5374 /*!
       
  5375     Constructs a copy of \a x.
       
  5376 
       
  5377     The data of the copy is shared (shallow copy): modifying one node
       
  5378     will also change the other. If you want to make a deep copy, use
       
  5379     cloneNode().
       
  5380 */
       
  5381 QDomComment::QDomComment(const QDomComment& x)
       
  5382     : QDomCharacterData(x)
       
  5383 {
       
  5384 }
       
  5385 
       
  5386 QDomComment::QDomComment(QDomCommentPrivate* n)
       
  5387     : QDomCharacterData(n)
       
  5388 {
       
  5389 }
       
  5390 
       
  5391 /*!
       
  5392     Assigns \a x to this DOM comment.
       
  5393 
       
  5394     The data of the copy is shared (shallow copy): modifying one node
       
  5395     will also change the other. If you want to make a deep copy, use
       
  5396     cloneNode().
       
  5397 */
       
  5398 QDomComment& QDomComment::operator= (const QDomComment& x)
       
  5399 {
       
  5400     return (QDomComment&) QDomNode::operator=(x);
       
  5401 }
       
  5402 
       
  5403 /*!
       
  5404     \fn QDomNode::NodeType QDomComment::nodeType() const
       
  5405 
       
  5406     Returns \c CommentNode.
       
  5407 */
       
  5408 
       
  5409 /**************************************************************
       
  5410  *
       
  5411  * QDomCDATASectionPrivate
       
  5412  *
       
  5413  **************************************************************/
       
  5414 
       
  5415 QDomCDATASectionPrivate::QDomCDATASectionPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent,
       
  5416                                                     const QString& val)
       
  5417     : QDomTextPrivate(d, parent, val)
       
  5418 {
       
  5419     name = QLatin1String("#cdata-section");
       
  5420 }
       
  5421 
       
  5422 QDomCDATASectionPrivate::QDomCDATASectionPrivate(QDomCDATASectionPrivate* n, bool deep)
       
  5423     : QDomTextPrivate(n, deep)
       
  5424 {
       
  5425 }
       
  5426 
       
  5427 QDomNodePrivate* QDomCDATASectionPrivate::cloneNode(bool deep)
       
  5428 {
       
  5429     QDomNodePrivate* p = new QDomCDATASectionPrivate(this, deep);
       
  5430     // We are not interested in this node
       
  5431     p->ref.deref();
       
  5432     return p;
       
  5433 }
       
  5434 
       
  5435 void QDomCDATASectionPrivate::save(QTextStream& s, int, int) const
       
  5436 {
       
  5437     // ### How do we escape "]]>" ?
       
  5438     // "]]>" is not allowed; so there should be none in value anyway
       
  5439     s << "<![CDATA[" << value << "]]>";
       
  5440 }
       
  5441 
       
  5442 /**************************************************************
       
  5443  *
       
  5444  * QDomCDATASection
       
  5445  *
       
  5446  **************************************************************/
       
  5447 
       
  5448 /*!
       
  5449     \class QDomCDATASection
       
  5450     \reentrant
       
  5451     \brief The QDomCDATASection class represents an XML CDATA section.
       
  5452 
       
  5453     \inmodule QtXml
       
  5454     \ingroup xml-tools
       
  5455 
       
  5456     CDATA sections are used to escape blocks of text containing
       
  5457     characters that would otherwise be regarded as markup. The only
       
  5458     delimiter that is recognized in a CDATA section is the "]]&gt;"
       
  5459     string that terminates the CDATA section. CDATA sections cannot be
       
  5460     nested. Their primary purpose is for including material such as
       
  5461     XML fragments, without needing to escape all the delimiters.
       
  5462 
       
  5463     Adjacent QDomCDATASection nodes are not merged by the
       
  5464     QDomNode::normalize() function.
       
  5465 
       
  5466     For further information about the Document Object Model see
       
  5467     \l{http://www.w3.org/TR/REC-DOM-Level-1/} and
       
  5468     \l{http://www.w3.org/TR/DOM-Level-2-Core/}.
       
  5469     For a more general introduction of the DOM implementation see the
       
  5470     QDomDocument documentation.
       
  5471 */
       
  5472 
       
  5473 /*!
       
  5474     Constructs an empty CDATA section. To create a CDATA section with
       
  5475     content, use the QDomDocument::createCDATASection() function.
       
  5476 */
       
  5477 QDomCDATASection::QDomCDATASection()
       
  5478     : QDomText()
       
  5479 {
       
  5480 }
       
  5481 
       
  5482 /*!
       
  5483     Constructs a copy of \a x.
       
  5484 
       
  5485     The data of the copy is shared (shallow copy): modifying one node
       
  5486     will also change the other. If you want to make a deep copy, use
       
  5487     cloneNode().
       
  5488 */
       
  5489 QDomCDATASection::QDomCDATASection(const QDomCDATASection& x)
       
  5490     : QDomText(x)
       
  5491 {
       
  5492 }
       
  5493 
       
  5494 QDomCDATASection::QDomCDATASection(QDomCDATASectionPrivate* n)
       
  5495     : QDomText(n)
       
  5496 {
       
  5497 }
       
  5498 
       
  5499 /*!
       
  5500     Assigns \a x to this CDATA section.
       
  5501 
       
  5502     The data of the copy is shared (shallow copy): modifying one node
       
  5503     will also change the other. If you want to make a deep copy, use
       
  5504     cloneNode().
       
  5505 */
       
  5506 QDomCDATASection& QDomCDATASection::operator= (const QDomCDATASection& x)
       
  5507 {
       
  5508     return (QDomCDATASection&) QDomNode::operator=(x);
       
  5509 }
       
  5510 
       
  5511 /*!
       
  5512     \fn QDomNode::NodeType QDomCDATASection::nodeType() const
       
  5513 
       
  5514     Returns \c CDATASection.
       
  5515 */
       
  5516 
       
  5517 /**************************************************************
       
  5518  *
       
  5519  * QDomNotationPrivate
       
  5520  *
       
  5521  **************************************************************/
       
  5522 
       
  5523 QDomNotationPrivate::QDomNotationPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent,
       
  5524                                             const QString& aname,
       
  5525                                             const QString& pub, const QString& sys)
       
  5526     : QDomNodePrivate(d, parent)
       
  5527 {
       
  5528     name = aname;
       
  5529     m_pub = pub;
       
  5530     m_sys = sys;
       
  5531 }
       
  5532 
       
  5533 QDomNotationPrivate::QDomNotationPrivate(QDomNotationPrivate* n, bool deep)
       
  5534     : QDomNodePrivate(n, deep)
       
  5535 {
       
  5536     m_sys = n->m_sys;
       
  5537     m_pub = n->m_pub;
       
  5538 }
       
  5539 
       
  5540 QDomNodePrivate* QDomNotationPrivate::cloneNode(bool deep)
       
  5541 {
       
  5542     QDomNodePrivate* p = new QDomNotationPrivate(this, deep);
       
  5543     // We are not interested in this node
       
  5544     p->ref.deref();
       
  5545     return p;
       
  5546 }
       
  5547 
       
  5548 void QDomNotationPrivate::save(QTextStream& s, int, int) const
       
  5549 {
       
  5550     s << "<!NOTATION " << name << ' ';
       
  5551     if (!m_pub.isNull())  {
       
  5552         s << "PUBLIC " << quotedValue(m_pub);
       
  5553         if (!m_sys.isNull())
       
  5554             s << ' ' << quotedValue(m_sys);
       
  5555     }  else {
       
  5556         s << "SYSTEM " << quotedValue(m_sys);
       
  5557     }
       
  5558     s << '>' << endl;
       
  5559 }
       
  5560 
       
  5561 /**************************************************************
       
  5562  *
       
  5563  * QDomNotation
       
  5564  *
       
  5565  **************************************************************/
       
  5566 
       
  5567 #define IMPL ((QDomNotationPrivate*)impl)
       
  5568 
       
  5569 /*!
       
  5570     \class QDomNotation
       
  5571     \reentrant
       
  5572     \brief The QDomNotation class represents an XML notation.
       
  5573 
       
  5574     \inmodule QtXml
       
  5575     \ingroup xml-tools
       
  5576 
       
  5577     A notation either declares, by name, the format of an unparsed
       
  5578     entity (see section 4.7 of the XML 1.0 specification), or is used
       
  5579     for formal declaration of processing instruction targets (see
       
  5580     section 2.6 of the XML 1.0 specification).
       
  5581 
       
  5582     DOM does not support editing notation nodes; they are therefore
       
  5583     read-only.
       
  5584 
       
  5585     A notation node does not have any parent.
       
  5586 
       
  5587     You can retrieve the publicId() and systemId() from a notation
       
  5588     node.
       
  5589 
       
  5590     For further information about the Document Object Model see
       
  5591     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5592     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5593     For a more general introduction of the DOM implementation see the
       
  5594     QDomDocument documentation.
       
  5595 */
       
  5596 
       
  5597 
       
  5598 /*!
       
  5599     Constructor.
       
  5600 */
       
  5601 QDomNotation::QDomNotation()
       
  5602     : QDomNode()
       
  5603 {
       
  5604 }
       
  5605 
       
  5606 /*!
       
  5607     Constructs a copy of \a x.
       
  5608 
       
  5609     The data of the copy is shared (shallow copy): modifying one node
       
  5610     will also change the other. If you want to make a deep copy, use
       
  5611     cloneNode().
       
  5612 */
       
  5613 QDomNotation::QDomNotation(const QDomNotation& x)
       
  5614     : QDomNode(x)
       
  5615 {
       
  5616 }
       
  5617 
       
  5618 QDomNotation::QDomNotation(QDomNotationPrivate* n)
       
  5619     : QDomNode(n)
       
  5620 {
       
  5621 }
       
  5622 
       
  5623 /*!
       
  5624     Assigns \a x to this DOM notation.
       
  5625 
       
  5626     The data of the copy is shared (shallow copy): modifying one node
       
  5627     will also change the other. If you want to make a deep copy, use
       
  5628     cloneNode().
       
  5629 */
       
  5630 QDomNotation& QDomNotation::operator= (const QDomNotation& x)
       
  5631 {
       
  5632     return (QDomNotation&) QDomNode::operator=(x);
       
  5633 }
       
  5634 
       
  5635 /*!
       
  5636     \fn QDomNode::NodeType QDomNotation::nodeType() const
       
  5637 
       
  5638     Returns \c NotationNode.
       
  5639 */
       
  5640 
       
  5641 /*!
       
  5642     Returns the public identifier of this notation.
       
  5643 */
       
  5644 QString QDomNotation::publicId() const
       
  5645 {
       
  5646     if (!impl)
       
  5647         return QString();
       
  5648     return IMPL->m_pub;
       
  5649 }
       
  5650 
       
  5651 /*!
       
  5652     Returns the system identifier of this notation.
       
  5653 */
       
  5654 QString QDomNotation::systemId() const
       
  5655 {
       
  5656     if (!impl)
       
  5657         return QString();
       
  5658     return IMPL->m_sys;
       
  5659 }
       
  5660 
       
  5661 #undef IMPL
       
  5662 
       
  5663 /**************************************************************
       
  5664  *
       
  5665  * QDomEntityPrivate
       
  5666  *
       
  5667  **************************************************************/
       
  5668 
       
  5669 QDomEntityPrivate::QDomEntityPrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent,
       
  5670                                         const QString& aname,
       
  5671                                         const QString& pub, const QString& sys, const QString& notation)
       
  5672     : QDomNodePrivate(d, parent)
       
  5673 {
       
  5674     name = aname;
       
  5675     m_pub = pub;
       
  5676     m_sys = sys;
       
  5677     m_notationName = notation;
       
  5678 }
       
  5679 
       
  5680 QDomEntityPrivate::QDomEntityPrivate(QDomEntityPrivate* n, bool deep)
       
  5681     : QDomNodePrivate(n, deep)
       
  5682 {
       
  5683     m_sys = n->m_sys;
       
  5684     m_pub = n->m_pub;
       
  5685     m_notationName = n->m_notationName;
       
  5686 }
       
  5687 
       
  5688 QDomNodePrivate* QDomEntityPrivate::cloneNode(bool deep)
       
  5689 {
       
  5690     QDomNodePrivate* p = new QDomEntityPrivate(this, deep);
       
  5691     // We are not interested in this node
       
  5692     p->ref.deref();
       
  5693     return p;
       
  5694 }
       
  5695 
       
  5696 /*
       
  5697   Encode an entity value upon saving.
       
  5698 */
       
  5699 static QByteArray encodeEntity(const QByteArray& str)
       
  5700 {
       
  5701     QByteArray tmp(str);
       
  5702     uint len = tmp.size();
       
  5703     uint i = 0;
       
  5704     const char* d = tmp.data();
       
  5705     while (i < len) {
       
  5706         if (d[i] == '%'){
       
  5707             tmp.replace(i, 1, "&#60;");
       
  5708             d = tmp;
       
  5709             len += 4;
       
  5710             i += 5;
       
  5711         }
       
  5712         else if (d[i] == '"') {
       
  5713             tmp.replace(i, 1, "&#34;");
       
  5714             d = tmp;
       
  5715             len += 4;
       
  5716             i += 5;
       
  5717         } else if (d[i] == '&' && i + 1 < len && d[i+1] == '#') {
       
  5718             // Dont encode &lt; or &quot; or &custom;.
       
  5719             // Only encode character references
       
  5720             tmp.replace(i, 1, "&#38;");
       
  5721             d = tmp;
       
  5722             len += 4;
       
  5723             i += 5;
       
  5724         } else {
       
  5725             ++i;
       
  5726         }
       
  5727     }
       
  5728 
       
  5729     return tmp;
       
  5730 }
       
  5731 
       
  5732 void QDomEntityPrivate::save(QTextStream& s, int, int) const
       
  5733 {
       
  5734     QString _name = name;
       
  5735     if (_name.startsWith(QLatin1Char('%')))
       
  5736         _name = QLatin1String("% ") + _name.mid(1);
       
  5737 
       
  5738     if (m_sys.isNull() && m_pub.isNull()) {
       
  5739         s << "<!ENTITY " << _name << " \"" << encodeEntity(value.toUtf8()) << "\">" << endl;
       
  5740     } else {
       
  5741         s << "<!ENTITY " << _name << ' ';
       
  5742         if (m_pub.isNull()) {
       
  5743             s << "SYSTEM " << quotedValue(m_sys);
       
  5744         } else {
       
  5745             s << "PUBLIC " << quotedValue(m_pub) << ' ' << quotedValue(m_sys);
       
  5746         }
       
  5747         if (! m_notationName.isNull()) {
       
  5748             s << " NDATA " << m_notationName;
       
  5749         }
       
  5750         s << '>' << endl;
       
  5751     }
       
  5752 }
       
  5753 
       
  5754 /**************************************************************
       
  5755  *
       
  5756  * QDomEntity
       
  5757  *
       
  5758  **************************************************************/
       
  5759 
       
  5760 #define IMPL ((QDomEntityPrivate*)impl)
       
  5761 
       
  5762 /*!
       
  5763     \class QDomEntity
       
  5764     \reentrant
       
  5765     \brief The QDomEntity class represents an XML entity.
       
  5766 
       
  5767     \inmodule QtXml
       
  5768     \ingroup xml-tools
       
  5769 
       
  5770     This class represents an entity in an XML document, either parsed
       
  5771     or unparsed. Note that this models the entity itself not the
       
  5772     entity declaration.
       
  5773 
       
  5774     DOM does not support editing entity nodes; if a user wants to make
       
  5775     changes to the contents of an entity, every related
       
  5776     QDomEntityReference node must be replaced in the DOM tree by a
       
  5777     clone of the entity's contents, and then the desired changes must
       
  5778     be made to each of the clones instead. All the descendants of an
       
  5779     entity node are read-only.
       
  5780 
       
  5781     An entity node does not have any parent.
       
  5782 
       
  5783     You can access the entity's publicId(), systemId() and
       
  5784     notationName() when available.
       
  5785 
       
  5786     For further information about the Document Object Model see
       
  5787     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5788     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5789     For a more general introduction of the DOM implementation see the
       
  5790     QDomDocument documentation.
       
  5791 */
       
  5792 
       
  5793 
       
  5794 /*!
       
  5795     Constructs an empty entity.
       
  5796 */
       
  5797 QDomEntity::QDomEntity()
       
  5798     : QDomNode()
       
  5799 {
       
  5800 }
       
  5801 
       
  5802 
       
  5803 /*!
       
  5804     Constructs a copy of \a x.
       
  5805 
       
  5806     The data of the copy is shared (shallow copy): modifying one node
       
  5807     will also change the other. If you want to make a deep copy, use
       
  5808     cloneNode().
       
  5809 */
       
  5810 QDomEntity::QDomEntity(const QDomEntity& x)
       
  5811     : QDomNode(x)
       
  5812 {
       
  5813 }
       
  5814 
       
  5815 QDomEntity::QDomEntity(QDomEntityPrivate* n)
       
  5816     : QDomNode(n)
       
  5817 {
       
  5818 }
       
  5819 
       
  5820 /*!
       
  5821     Assigns \a x to this DOM entity.
       
  5822 
       
  5823     The data of the copy is shared (shallow copy): modifying one node
       
  5824     will also change the other. If you want to make a deep copy, use
       
  5825     cloneNode().
       
  5826 */
       
  5827 QDomEntity& QDomEntity::operator= (const QDomEntity& x)
       
  5828 {
       
  5829     return (QDomEntity&) QDomNode::operator=(x);
       
  5830 }
       
  5831 
       
  5832 /*!
       
  5833     \fn QDomNode::NodeType QDomEntity::nodeType() const
       
  5834 
       
  5835     Returns \c EntityNode.
       
  5836 */
       
  5837 
       
  5838 /*!
       
  5839     Returns the public identifier associated with this entity. If the
       
  5840     public identifier was not specified an empty string is returned.
       
  5841 */
       
  5842 QString QDomEntity::publicId() const
       
  5843 {
       
  5844     if (!impl)
       
  5845         return QString();
       
  5846     return IMPL->m_pub;
       
  5847 }
       
  5848 
       
  5849 /*!
       
  5850     Returns the system identifier associated with this entity. If the
       
  5851     system identifier was not specified an empty string is returned.
       
  5852 */
       
  5853 QString QDomEntity::systemId() const
       
  5854 {
       
  5855     if (!impl)
       
  5856         return QString();
       
  5857     return IMPL->m_sys;
       
  5858 }
       
  5859 
       
  5860 /*!
       
  5861     For unparsed entities this function returns the name of the
       
  5862     notation for the entity. For parsed entities this function returns
       
  5863     an empty string.
       
  5864 */
       
  5865 QString QDomEntity::notationName() const
       
  5866 {
       
  5867     if (!impl)
       
  5868         return QString();
       
  5869     return IMPL->m_notationName;
       
  5870 }
       
  5871 
       
  5872 #undef IMPL
       
  5873 
       
  5874 /**************************************************************
       
  5875  *
       
  5876  * QDomEntityReferencePrivate
       
  5877  *
       
  5878  **************************************************************/
       
  5879 
       
  5880 QDomEntityReferencePrivate::QDomEntityReferencePrivate(QDomDocumentPrivate* d, QDomNodePrivate* parent, const QString& aname)
       
  5881     : QDomNodePrivate(d, parent)
       
  5882 {
       
  5883     name = aname;
       
  5884 }
       
  5885 
       
  5886 QDomEntityReferencePrivate::QDomEntityReferencePrivate(QDomNodePrivate* n, bool deep)
       
  5887     : QDomNodePrivate(n, deep)
       
  5888 {
       
  5889 }
       
  5890 
       
  5891 QDomNodePrivate* QDomEntityReferencePrivate::cloneNode(bool deep)
       
  5892 {
       
  5893     QDomNodePrivate* p = new QDomEntityReferencePrivate(this, deep);
       
  5894     // We are not interested in this node
       
  5895     p->ref.deref();
       
  5896     return p;
       
  5897 }
       
  5898 
       
  5899 void QDomEntityReferencePrivate::save(QTextStream& s, int, int) const
       
  5900 {
       
  5901     s << '&' << name << ';';
       
  5902 }
       
  5903 
       
  5904 /**************************************************************
       
  5905  *
       
  5906  * QDomEntityReference
       
  5907  *
       
  5908  **************************************************************/
       
  5909 
       
  5910 /*!
       
  5911     \class QDomEntityReference
       
  5912     \reentrant
       
  5913     \brief The QDomEntityReference class represents an XML entity reference.
       
  5914 
       
  5915     \inmodule QtXml
       
  5916     \ingroup xml-tools
       
  5917 
       
  5918     A QDomEntityReference object may be inserted into the DOM tree
       
  5919     when an entity reference is in the source document, or when the
       
  5920     user wishes to insert an entity reference.
       
  5921 
       
  5922     Note that character references and references to predefined
       
  5923     entities are expanded by the XML processor so that characters are
       
  5924     represented by their Unicode equivalent rather than by an entity
       
  5925     reference.
       
  5926 
       
  5927     Moreover, the XML processor may completely expand references to
       
  5928     entities while building the DOM tree, instead of providing
       
  5929     QDomEntityReference objects.
       
  5930 
       
  5931     If it does provide such objects, then for a given entity reference
       
  5932     node, it may be that there is no entity node representing the
       
  5933     referenced entity; but if such an entity exists, then the child
       
  5934     list of the entity reference node is the same as that of the
       
  5935     entity  node. As with the entity node, all descendants of the
       
  5936     entity reference are read-only.
       
  5937 
       
  5938     For further information about the Document Object Model see
       
  5939     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  5940     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  5941     For a more general introduction of the DOM implementation see the
       
  5942     QDomDocument documentation.
       
  5943 */
       
  5944 
       
  5945 /*!
       
  5946     Constructs an empty entity reference. Use
       
  5947     QDomDocument::createEntityReference() to create a entity reference
       
  5948     with content.
       
  5949 */
       
  5950 QDomEntityReference::QDomEntityReference()
       
  5951     : QDomNode()
       
  5952 {
       
  5953 }
       
  5954 
       
  5955 /*!
       
  5956     Constructs a copy of \a x.
       
  5957 
       
  5958     The data of the copy is shared (shallow copy): modifying one node
       
  5959     will also change the other. If you want to make a deep copy, use
       
  5960     cloneNode().
       
  5961 */
       
  5962 QDomEntityReference::QDomEntityReference(const QDomEntityReference& x)
       
  5963     : QDomNode(x)
       
  5964 {
       
  5965 }
       
  5966 
       
  5967 QDomEntityReference::QDomEntityReference(QDomEntityReferencePrivate* n)
       
  5968     : QDomNode(n)
       
  5969 {
       
  5970 }
       
  5971 
       
  5972 /*!
       
  5973     Assigns \a x to this entity reference.
       
  5974 
       
  5975     The data of the copy is shared (shallow copy): modifying one node
       
  5976     will also change the other. If you want to make a deep copy, use
       
  5977     cloneNode().
       
  5978 */
       
  5979 QDomEntityReference& QDomEntityReference::operator= (const QDomEntityReference& x)
       
  5980 {
       
  5981     return (QDomEntityReference&) QDomNode::operator=(x);
       
  5982 }
       
  5983 
       
  5984 /*!
       
  5985     \fn QDomNode::NodeType QDomEntityReference::nodeType() const
       
  5986 
       
  5987     Returns \c EntityReference.
       
  5988 */
       
  5989 
       
  5990 /**************************************************************
       
  5991  *
       
  5992  * QDomProcessingInstructionPrivate
       
  5993  *
       
  5994  **************************************************************/
       
  5995 
       
  5996 QDomProcessingInstructionPrivate::QDomProcessingInstructionPrivate(QDomDocumentPrivate* d,
       
  5997         QDomNodePrivate* parent, const QString& target, const QString& data)
       
  5998     : QDomNodePrivate(d, parent)
       
  5999 {
       
  6000     name = target;
       
  6001     value = data;
       
  6002 }
       
  6003 
       
  6004 QDomProcessingInstructionPrivate::QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate* n, bool deep)
       
  6005     : QDomNodePrivate(n, deep)
       
  6006 {
       
  6007 }
       
  6008 
       
  6009 
       
  6010 QDomNodePrivate* QDomProcessingInstructionPrivate::cloneNode(bool deep)
       
  6011 {
       
  6012     QDomNodePrivate* p = new QDomProcessingInstructionPrivate(this, deep);
       
  6013     // We are not interested in this node
       
  6014     p->ref.deref();
       
  6015     return p;
       
  6016 }
       
  6017 
       
  6018 void QDomProcessingInstructionPrivate::save(QTextStream& s, int, int) const
       
  6019 {
       
  6020     s << "<?" << name << ' ' << value << "?>" << endl;
       
  6021 }
       
  6022 
       
  6023 /**************************************************************
       
  6024  *
       
  6025  * QDomProcessingInstruction
       
  6026  *
       
  6027  **************************************************************/
       
  6028 
       
  6029 /*!
       
  6030     \class QDomProcessingInstruction
       
  6031     \reentrant
       
  6032     \brief The QDomProcessingInstruction class represents an XML processing
       
  6033     instruction.
       
  6034 
       
  6035     \inmodule QtXml
       
  6036     \ingroup xml-tools
       
  6037 
       
  6038     Processing instructions are used in XML to keep processor-specific
       
  6039     information in the text of the document.
       
  6040 
       
  6041     The XML declaration that appears at the top of an XML document,
       
  6042     typically \tt{<?xml version='1.0' encoding='UTF-8'?>}, is treated by QDom as a
       
  6043     processing instruction. This is unfortunate, since the XML declaration is
       
  6044     not a processing instruction; among other differences, it cannot be
       
  6045     inserted into a document anywhere but on the first line.
       
  6046 
       
  6047     Do not use this function to create an xml declaration, since although it
       
  6048     has the same syntax as a processing instruction, it isn't, and might not
       
  6049     be treated by QDom as such.
       
  6050 
       
  6051     The content of the processing instruction is retrieved with data()
       
  6052     and set with setData(). The processing instruction's target is
       
  6053     retrieved with target().
       
  6054 
       
  6055     For further information about the Document Object Model see
       
  6056     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  6057     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}.
       
  6058     For a more general introduction of the DOM implementation see the
       
  6059     QDomDocument documentation.
       
  6060 */
       
  6061 
       
  6062 /*!
       
  6063     Constructs an empty processing instruction. Use
       
  6064     QDomDocument::createProcessingInstruction() to create a processing
       
  6065     instruction with content.
       
  6066 */
       
  6067 QDomProcessingInstruction::QDomProcessingInstruction()
       
  6068     : QDomNode()
       
  6069 {
       
  6070 }
       
  6071 
       
  6072 /*!
       
  6073     Constructs a copy of \a x.
       
  6074 
       
  6075     The data of the copy is shared (shallow copy): modifying one node
       
  6076     will also change the other. If you want to make a deep copy, use
       
  6077     cloneNode().
       
  6078 */
       
  6079 QDomProcessingInstruction::QDomProcessingInstruction(const QDomProcessingInstruction& x)
       
  6080     : QDomNode(x)
       
  6081 {
       
  6082 }
       
  6083 
       
  6084 QDomProcessingInstruction::QDomProcessingInstruction(QDomProcessingInstructionPrivate* n)
       
  6085     : QDomNode(n)
       
  6086 {
       
  6087 }
       
  6088 
       
  6089 /*!
       
  6090     Assigns \a x to this processing instruction.
       
  6091 
       
  6092     The data of the copy is shared (shallow copy): modifying one node
       
  6093     will also change the other. If you want to make a deep copy, use
       
  6094     cloneNode().
       
  6095 */
       
  6096 QDomProcessingInstruction& QDomProcessingInstruction::operator= (const QDomProcessingInstruction& x)
       
  6097 {
       
  6098     return (QDomProcessingInstruction&) QDomNode::operator=(x);
       
  6099 }
       
  6100 
       
  6101 /*!
       
  6102     \fn QDomNode::NodeType QDomProcessingInstruction::nodeType() const
       
  6103 
       
  6104     Returns \c ProcessingInstructionNode.
       
  6105 */
       
  6106 
       
  6107 /*!
       
  6108     Returns the target of this processing instruction.
       
  6109 
       
  6110     \sa data()
       
  6111 */
       
  6112 QString QDomProcessingInstruction::target() const
       
  6113 {
       
  6114     if (!impl)
       
  6115         return QString();
       
  6116     return impl->nodeName();
       
  6117 }
       
  6118 
       
  6119 /*!
       
  6120     Returns the content of this processing instruction.
       
  6121 
       
  6122     \sa setData() target()
       
  6123 */
       
  6124 QString QDomProcessingInstruction::data() const
       
  6125 {
       
  6126     if (!impl)
       
  6127         return QString();
       
  6128     return impl->nodeValue();
       
  6129 }
       
  6130 
       
  6131 /*!
       
  6132     Sets the data contained in the processing instruction to \a d.
       
  6133 
       
  6134     \sa data()
       
  6135 */
       
  6136 void QDomProcessingInstruction::setData(const QString& d)
       
  6137 {
       
  6138     if (!impl)
       
  6139         return;
       
  6140     impl->setNodeValue(d);
       
  6141 }
       
  6142 
       
  6143 /**************************************************************
       
  6144  *
       
  6145  * QDomDocumentPrivate
       
  6146  *
       
  6147  **************************************************************/
       
  6148 
       
  6149 QDomDocumentPrivate::QDomDocumentPrivate()
       
  6150     : QDomNodePrivate(0),
       
  6151       impl(new QDomImplementationPrivate),
       
  6152       nodeListTime(1)
       
  6153 {
       
  6154     type = new QDomDocumentTypePrivate(this, this);
       
  6155     type->ref.deref();
       
  6156 
       
  6157     name = QLatin1String("#document");
       
  6158 }
       
  6159 
       
  6160 QDomDocumentPrivate::QDomDocumentPrivate(const QString& aname)
       
  6161     : QDomNodePrivate(0),
       
  6162       impl(new QDomImplementationPrivate),
       
  6163       nodeListTime(1)
       
  6164 {
       
  6165     type = new QDomDocumentTypePrivate(this, this);
       
  6166     type->ref.deref();
       
  6167     type->name = aname;
       
  6168 
       
  6169     name = QLatin1String("#document");
       
  6170 }
       
  6171 
       
  6172 QDomDocumentPrivate::QDomDocumentPrivate(QDomDocumentTypePrivate* dt)
       
  6173     : QDomNodePrivate(0),
       
  6174       impl(new QDomImplementationPrivate),
       
  6175       nodeListTime(1)
       
  6176 {
       
  6177     if (dt != 0) {
       
  6178         type = dt;
       
  6179     } else {
       
  6180         type = new QDomDocumentTypePrivate(this, this);
       
  6181         type->ref.deref();
       
  6182     }
       
  6183 
       
  6184     name = QLatin1String("#document");
       
  6185 }
       
  6186 
       
  6187 QDomDocumentPrivate::QDomDocumentPrivate(QDomDocumentPrivate* n, bool deep)
       
  6188     : QDomNodePrivate(n, deep),
       
  6189       impl(n->impl->clone()),
       
  6190       nodeListTime(1)
       
  6191 {
       
  6192     type = static_cast<QDomDocumentTypePrivate*>(n->type->cloneNode());
       
  6193     type->setParent(this);
       
  6194 }
       
  6195 
       
  6196 QDomDocumentPrivate::~QDomDocumentPrivate()
       
  6197 {
       
  6198 }
       
  6199 
       
  6200 void QDomDocumentPrivate::clear()
       
  6201 {
       
  6202     impl.reset();
       
  6203     type.reset();
       
  6204     QDomNodePrivate::clear();
       
  6205 }
       
  6206 
       
  6207 static void initializeReader(QXmlSimpleReader &reader, bool namespaceProcessing)
       
  6208 {
       
  6209     reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), namespaceProcessing);
       
  6210     reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), !namespaceProcessing);
       
  6211     reader.setFeature(QLatin1String("http://trolltech.com/xml/features/report-whitespace-only-CharData"), false); // Shouldn't change in Qt 4
       
  6212 }
       
  6213 
       
  6214 bool QDomDocumentPrivate::setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6215 {
       
  6216     QXmlSimpleReader reader;
       
  6217     initializeReader(reader, namespaceProcessing);
       
  6218     return setContent(source, &reader, errorMsg, errorLine, errorColumn);
       
  6219 }
       
  6220 
       
  6221 bool QDomDocumentPrivate::setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6222 {
       
  6223     clear();
       
  6224     impl = new QDomImplementationPrivate;
       
  6225     type = new QDomDocumentTypePrivate(this, this);
       
  6226     type->ref.deref();
       
  6227 
       
  6228     bool namespaceProcessing = reader->feature(QLatin1String("http://xml.org/sax/features/namespaces"))
       
  6229         && !reader->feature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"));
       
  6230 
       
  6231     QDomHandler hnd(this, namespaceProcessing);
       
  6232     reader->setContentHandler(&hnd);
       
  6233     reader->setErrorHandler(&hnd);
       
  6234     reader->setLexicalHandler(&hnd);
       
  6235     reader->setDeclHandler(&hnd);
       
  6236     reader->setDTDHandler(&hnd);
       
  6237 
       
  6238     if (!reader->parse(source)) {
       
  6239         if (errorMsg)
       
  6240             *errorMsg = hnd.errorMsg;
       
  6241         if (errorLine)
       
  6242             *errorLine = hnd.errorLine;
       
  6243         if (errorColumn)
       
  6244             *errorColumn = hnd.errorColumn;
       
  6245         return false;
       
  6246     }
       
  6247 
       
  6248     return true;
       
  6249 }
       
  6250 
       
  6251 QDomNodePrivate* QDomDocumentPrivate::cloneNode(bool deep)
       
  6252 {
       
  6253     QDomNodePrivate *p = new QDomDocumentPrivate(this, deep);
       
  6254     // We are not interested in this node
       
  6255     p->ref.deref();
       
  6256     return p;
       
  6257 }
       
  6258 
       
  6259 QDomElementPrivate* QDomDocumentPrivate::documentElement()
       
  6260 {
       
  6261     QDomNodePrivate *p = first;
       
  6262     while (p && !p->isElement())
       
  6263         p = p->next;
       
  6264 
       
  6265     return static_cast<QDomElementPrivate *>(p);
       
  6266 }
       
  6267 
       
  6268 QDomElementPrivate* QDomDocumentPrivate::createElement(const QString &tagName)
       
  6269 {
       
  6270     bool ok;
       
  6271     QString fixedName = fixedXmlName(tagName, &ok);
       
  6272     if (!ok)
       
  6273         return 0;
       
  6274 
       
  6275     QDomElementPrivate *e = new QDomElementPrivate(this, 0, fixedName);
       
  6276     e->ref.deref();
       
  6277     return e;
       
  6278 }
       
  6279 
       
  6280 QDomElementPrivate* QDomDocumentPrivate::createElementNS(const QString &nsURI, const QString &qName)
       
  6281 {
       
  6282     bool ok;
       
  6283     QString fixedName = fixedXmlName(qName, &ok, true);
       
  6284     if (!ok)
       
  6285         return 0;
       
  6286 
       
  6287     QDomElementPrivate *e = new QDomElementPrivate(this, 0, nsURI, fixedName);
       
  6288     e->ref.deref();
       
  6289     return e;
       
  6290 }
       
  6291 
       
  6292 QDomDocumentFragmentPrivate* QDomDocumentPrivate::createDocumentFragment()
       
  6293 {
       
  6294     QDomDocumentFragmentPrivate *f = new QDomDocumentFragmentPrivate(this, (QDomNodePrivate*)0);
       
  6295     f->ref.deref();
       
  6296     return f;
       
  6297 }
       
  6298 
       
  6299 QDomTextPrivate* QDomDocumentPrivate::createTextNode(const QString &data)
       
  6300 {
       
  6301     bool ok;
       
  6302     QString fixedData = fixedCharData(data, &ok);
       
  6303     if (!ok)
       
  6304         return 0;
       
  6305 
       
  6306     QDomTextPrivate *t = new QDomTextPrivate(this, 0, fixedData);
       
  6307     t->ref.deref();
       
  6308     return t;
       
  6309 }
       
  6310 
       
  6311 QDomCommentPrivate* QDomDocumentPrivate::createComment(const QString &data)
       
  6312 {
       
  6313     bool ok;
       
  6314     QString fixedData = fixedComment(data, &ok);
       
  6315     if (!ok)
       
  6316         return 0;
       
  6317 
       
  6318     QDomCommentPrivate *c = new QDomCommentPrivate(this, 0, fixedData);
       
  6319     c->ref.deref();
       
  6320     return c;
       
  6321 }
       
  6322 
       
  6323 QDomCDATASectionPrivate* QDomDocumentPrivate::createCDATASection(const QString &data)
       
  6324 {
       
  6325     bool ok;
       
  6326     QString fixedData = fixedCDataSection(data, &ok);
       
  6327     if (!ok)
       
  6328         return 0;
       
  6329 
       
  6330     QDomCDATASectionPrivate *c = new QDomCDATASectionPrivate(this, 0, fixedData);
       
  6331     c->ref.deref();
       
  6332     return c;
       
  6333 }
       
  6334 
       
  6335 QDomProcessingInstructionPrivate* QDomDocumentPrivate::createProcessingInstruction(const QString &target,
       
  6336                                                                                    const QString &data)
       
  6337 {
       
  6338     bool ok;
       
  6339     QString fixedData = fixedPIData(data, &ok);
       
  6340     if (!ok)
       
  6341         return 0;
       
  6342     // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
       
  6343     QString fixedTarget = fixedXmlName(target, &ok);
       
  6344     if (!ok)
       
  6345         return 0;
       
  6346 
       
  6347     QDomProcessingInstructionPrivate *p = new QDomProcessingInstructionPrivate(this, 0, fixedTarget, fixedData);
       
  6348     p->ref.deref();
       
  6349     return p;
       
  6350 }
       
  6351 QDomAttrPrivate* QDomDocumentPrivate::createAttribute(const QString &aname)
       
  6352 {
       
  6353     bool ok;
       
  6354     QString fixedName = fixedXmlName(aname, &ok);
       
  6355     if (!ok)
       
  6356         return 0;
       
  6357 
       
  6358     QDomAttrPrivate *a = new QDomAttrPrivate(this, 0, fixedName);
       
  6359     a->ref.deref();
       
  6360     return a;
       
  6361 }
       
  6362 
       
  6363 QDomAttrPrivate* QDomDocumentPrivate::createAttributeNS(const QString &nsURI, const QString &qName)
       
  6364 {
       
  6365     bool ok;
       
  6366     QString fixedName = fixedXmlName(qName, &ok, true);
       
  6367     if (!ok)
       
  6368         return 0;
       
  6369 
       
  6370     QDomAttrPrivate *a = new QDomAttrPrivate(this, 0, nsURI, fixedName);
       
  6371     a->ref.deref();
       
  6372     return a;
       
  6373 }
       
  6374 
       
  6375 QDomEntityReferencePrivate* QDomDocumentPrivate::createEntityReference(const QString &aname)
       
  6376 {
       
  6377     bool ok;
       
  6378     QString fixedName = fixedXmlName(aname, &ok);
       
  6379     if (!ok)
       
  6380         return 0;
       
  6381 
       
  6382     QDomEntityReferencePrivate *e = new QDomEntityReferencePrivate(this, 0, fixedName);
       
  6383     e->ref.deref();
       
  6384     return e;
       
  6385 }
       
  6386 
       
  6387 QDomNodePrivate* QDomDocumentPrivate::importNode(const QDomNodePrivate *importedNode, bool deep)
       
  6388 {
       
  6389     QDomNodePrivate *node = 0;
       
  6390     switch (importedNode->nodeType()) {
       
  6391         case QDomNode::AttributeNode:
       
  6392             node = new QDomAttrPrivate((QDomAttrPrivate*)importedNode, true);
       
  6393             break;
       
  6394         case QDomNode::DocumentFragmentNode:
       
  6395             node = new QDomDocumentFragmentPrivate((QDomDocumentFragmentPrivate*)importedNode, deep);
       
  6396             break;
       
  6397         case QDomNode::ElementNode:
       
  6398             node = new QDomElementPrivate((QDomElementPrivate*)importedNode, deep);
       
  6399             break;
       
  6400         case QDomNode::EntityNode:
       
  6401             node = new QDomEntityPrivate((QDomEntityPrivate*)importedNode, deep);
       
  6402             break;
       
  6403         case QDomNode::EntityReferenceNode:
       
  6404             node = new QDomEntityReferencePrivate((QDomEntityReferencePrivate*)importedNode, false);
       
  6405             break;
       
  6406         case QDomNode::NotationNode:
       
  6407             node = new QDomNotationPrivate((QDomNotationPrivate*)importedNode, deep);
       
  6408             break;
       
  6409         case QDomNode::ProcessingInstructionNode:
       
  6410             node = new QDomProcessingInstructionPrivate((QDomProcessingInstructionPrivate*)importedNode, deep);
       
  6411             break;
       
  6412         case QDomNode::TextNode:
       
  6413             node = new QDomTextPrivate((QDomTextPrivate*)importedNode, deep);
       
  6414             break;
       
  6415         case QDomNode::CDATASectionNode:
       
  6416             node = new QDomCDATASectionPrivate((QDomCDATASectionPrivate*)importedNode, deep);
       
  6417             break;
       
  6418         case QDomNode::CommentNode:
       
  6419             node = new QDomCommentPrivate((QDomCommentPrivate*)importedNode, deep);
       
  6420             break;
       
  6421         default:
       
  6422             break;
       
  6423     }
       
  6424     if (node) {
       
  6425         node->setOwnerDocument(this);
       
  6426         // The QDomNode constructor increases the refcount, so deref first to
       
  6427         // keep refcount balanced.
       
  6428         node->ref.deref();
       
  6429     }
       
  6430     return node;
       
  6431 }
       
  6432 
       
  6433 void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNode::EncodingPolicy encUsed) const
       
  6434 {
       
  6435     const QDomNodePrivate* n = first;
       
  6436 
       
  6437     if(encUsed == QDomNode::EncodingFromDocument) {
       
  6438 #ifndef QT_NO_TEXTCODEC
       
  6439         const QDomNodePrivate* n = first;
       
  6440 
       
  6441         QTextCodec *codec = 0;
       
  6442 
       
  6443         if (n && n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml")) {
       
  6444             // we have an XML declaration
       
  6445             QString data = n->nodeValue();
       
  6446             QRegExp encoding(QString::fromLatin1("encoding\\s*=\\s*((\"([^\"]*)\")|('([^']*)'))"));
       
  6447             encoding.indexIn(data);
       
  6448             QString enc = encoding.cap(3);
       
  6449             if (enc.isEmpty())
       
  6450                 enc = encoding.cap(5);
       
  6451             if (!enc.isEmpty())
       
  6452                 codec = QTextCodec::codecForName(enc.toLatin1().data());
       
  6453         }
       
  6454         if (!codec)
       
  6455             codec = QTextCodec::codecForName("UTF-8");
       
  6456         if (codec)
       
  6457             s.setCodec(codec);
       
  6458 #endif
       
  6459         bool doc = false;
       
  6460 
       
  6461         while (n) {
       
  6462             if (!doc && !(n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml"))) {
       
  6463                 // save doctype after XML declaration
       
  6464                 type->save(s, 0, indent);
       
  6465                 doc = true;
       
  6466             }
       
  6467             n->save(s, 0, indent);
       
  6468             n = n->next;
       
  6469         }
       
  6470     }
       
  6471     else {
       
  6472 
       
  6473         // Write out the XML declaration.
       
  6474 #ifdef QT_NO_TEXTCODEC
       
  6475         const QLatin1String codecName("iso-8859-1");
       
  6476 #else
       
  6477         const QTextCodec *const codec = s.codec();
       
  6478         Q_ASSERT_X(codec, "QDomNode::save()", "A codec must be specified in the text stream.");
       
  6479         const QByteArray codecName = codec->name();
       
  6480 #endif
       
  6481 
       
  6482         s << "<?xml version=\"1.0\" encoding=\""
       
  6483           << codecName
       
  6484           << "\"?>\n";
       
  6485 
       
  6486         //  Skip the first processing instruction by name "xml", if any such exists.
       
  6487         const QDomNodePrivate* startNode = n;
       
  6488 
       
  6489         // First, we try to find the PI and sets the startNode to the one appearing after it.
       
  6490         while (n) {
       
  6491             if(n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml")) {
       
  6492                 startNode = n->next;
       
  6493                 break;
       
  6494             }
       
  6495             else
       
  6496                 n = n->next;
       
  6497         }
       
  6498 
       
  6499         // Now we serialize all the nodes after the faked XML declaration(the PI).
       
  6500         while(startNode) {
       
  6501             startNode->save(s, 0, indent);
       
  6502             startNode = startNode->next;
       
  6503         }
       
  6504     }
       
  6505 }
       
  6506 
       
  6507 /**************************************************************
       
  6508  *
       
  6509  * QDomDocument
       
  6510  *
       
  6511  **************************************************************/
       
  6512 
       
  6513 #define IMPL ((QDomDocumentPrivate*)impl)
       
  6514 
       
  6515 /*!
       
  6516     \class QDomDocument
       
  6517     \reentrant
       
  6518     \brief The QDomDocument class represents an XML document.
       
  6519 
       
  6520     \inmodule QtXml
       
  6521 
       
  6522     \ingroup xml-tools
       
  6523 
       
  6524     The QDomDocument class represents the entire XML document.
       
  6525     Conceptually, it is the root of the document tree, and provides
       
  6526     the primary access to the document's data.
       
  6527 
       
  6528     Since elements, text nodes, comments, processing instructions,
       
  6529     etc., cannot exist outside the context of a document, the document
       
  6530     class also contains the factory functions needed to create these
       
  6531     objects. The node objects created have an ownerDocument() function
       
  6532     which associates them with the document within whose context they
       
  6533     were created. The DOM classes that will be used most often are
       
  6534     QDomNode, QDomDocument, QDomElement and QDomText.
       
  6535 
       
  6536     The parsed XML is represented internally by a tree of objects that
       
  6537     can be accessed using the various QDom classes. All QDom classes
       
  6538     only \e reference objects in the internal tree. The internal
       
  6539     objects in the DOM tree will get deleted once the last QDom
       
  6540     object referencing them and the QDomDocument itself are deleted.
       
  6541 
       
  6542     Creation of elements, text nodes, etc. is done using the various
       
  6543     factory functions provided in this class. Using the default
       
  6544     constructors of the QDom classes will only result in empty
       
  6545     objects that cannot be manipulated or inserted into the Document.
       
  6546 
       
  6547     The QDomDocument class has several functions for creating document
       
  6548     data, for example, createElement(), createTextNode(),
       
  6549     createComment(), createCDATASection(),
       
  6550     createProcessingInstruction(), createAttribute() and
       
  6551     createEntityReference(). Some of these functions have versions
       
  6552     that support namespaces, i.e. createElementNS() and
       
  6553     createAttributeNS(). The createDocumentFragment() function is used
       
  6554     to hold parts of the document; this is useful for manipulating for
       
  6555     complex documents.
       
  6556 
       
  6557     The entire content of the document is set with setContent(). This
       
  6558     function parses the string it is passed as an XML document and
       
  6559     creates the DOM tree that represents the document. The root
       
  6560     element is available using documentElement(). The textual
       
  6561     representation of the document can be obtained using toString().
       
  6562 
       
  6563     It is possible to insert a node from another document into the
       
  6564     document using importNode().
       
  6565 
       
  6566     You can obtain a list of all the elements that have a particular
       
  6567     tag with elementsByTagName() or with elementsByTagNameNS().
       
  6568 
       
  6569     The QDom classes are typically used as follows:
       
  6570     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 16
       
  6571 
       
  6572     Once \c doc and \c elem go out of scope, the whole internal tree
       
  6573     representing the XML document is deleted.
       
  6574 
       
  6575     To create a document using DOM use code like this:
       
  6576     \snippet doc/src/snippets/code/src_xml_dom_qdom.cpp 17
       
  6577 
       
  6578     For further information about the Document Object Model see
       
  6579     the Document Object Model (DOM)
       
  6580     \l{http://www.w3.org/TR/REC-DOM-Level-1/}{Level 1} and
       
  6581     \l{http://www.w3.org/TR/DOM-Level-2-Core/}{Level 2 Core}
       
  6582     Specifications.
       
  6583 
       
  6584     \sa {DOM Bookmarks Example}, {Simple DOM Model Example}
       
  6585 */
       
  6586 
       
  6587 
       
  6588 /*!
       
  6589     Constructs an empty document.
       
  6590 */
       
  6591 QDomDocument::QDomDocument()
       
  6592 {
       
  6593     impl = 0;
       
  6594 }
       
  6595 
       
  6596 /*!
       
  6597     Creates a document and sets the name of the document type to \a
       
  6598     name.
       
  6599 */
       
  6600 QDomDocument::QDomDocument(const QString& name)
       
  6601 {
       
  6602     // We take over ownership
       
  6603     impl = new QDomDocumentPrivate(name);
       
  6604 }
       
  6605 
       
  6606 /*!
       
  6607     Creates a document with the document type \a doctype.
       
  6608 
       
  6609     \sa QDomImplementation::createDocumentType()
       
  6610 */
       
  6611 QDomDocument::QDomDocument(const QDomDocumentType& doctype)
       
  6612 {
       
  6613     impl = new QDomDocumentPrivate((QDomDocumentTypePrivate*)(doctype.impl));
       
  6614 }
       
  6615 
       
  6616 /*!
       
  6617     Constructs a copy of \a x.
       
  6618 
       
  6619     The data of the copy is shared (shallow copy): modifying one node
       
  6620     will also change the other. If you want to make a deep copy, use
       
  6621     cloneNode().
       
  6622 */
       
  6623 QDomDocument::QDomDocument(const QDomDocument& x)
       
  6624     : QDomNode(x)
       
  6625 {
       
  6626 }
       
  6627 
       
  6628 QDomDocument::QDomDocument(QDomDocumentPrivate* x)
       
  6629     : QDomNode(x)
       
  6630 {
       
  6631 }
       
  6632 
       
  6633 /*!
       
  6634     Assigns \a x to this DOM document.
       
  6635 
       
  6636     The data of the copy is shared (shallow copy): modifying one node
       
  6637     will also change the other. If you want to make a deep copy, use
       
  6638     cloneNode().
       
  6639 */
       
  6640 QDomDocument& QDomDocument::operator= (const QDomDocument& x)
       
  6641 {
       
  6642     return (QDomDocument&) QDomNode::operator=(x);
       
  6643 }
       
  6644 
       
  6645 /*!
       
  6646     Destroys the object and frees its resources.
       
  6647 */
       
  6648 QDomDocument::~QDomDocument()
       
  6649 {
       
  6650 }
       
  6651 
       
  6652 /*!
       
  6653     \overload
       
  6654 
       
  6655     This function reads the XML document from the string \a text, returning
       
  6656     true if the content was successfully parsed; otherwise returns false.
       
  6657     Since \a text is already a Unicode string, no encoding detection
       
  6658     is done.
       
  6659 */
       
  6660 bool QDomDocument::setContent(const QString& text, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6661 {
       
  6662     if (!impl)
       
  6663         impl = new QDomDocumentPrivate();
       
  6664     QXmlInputSource source;
       
  6665     source.setData(text);
       
  6666     return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn);
       
  6667 }
       
  6668 
       
  6669 /*!
       
  6670     \nonreentrant
       
  6671 
       
  6672     This function parses the XML document from the byte array \a
       
  6673     data and sets it as the content of the document. It tries to
       
  6674     detect the encoding of the document as required by the XML
       
  6675     specification.
       
  6676 
       
  6677     If \a namespaceProcessing is true, the parser recognizes
       
  6678     namespaces in the XML file and sets the prefix name, local name
       
  6679     and namespace URI to appropriate values. If \a namespaceProcessing
       
  6680     is false, the parser does no namespace processing when it reads
       
  6681     the XML file.
       
  6682 
       
  6683     If a parse error occurs, this function returns false and the error
       
  6684     message is placed in \c{*}\a{errorMsg}, the line number in
       
  6685     \c{*}\a{errorLine} and the column number in \c{*}\a{errorColumn}
       
  6686     (unless the associated pointer is set to 0); otherwise this
       
  6687     function returns true. The various error messages are described in
       
  6688     the QXmlParseException class documentation. Note that, if you
       
  6689     want to display these error messages to your application's users,
       
  6690     they will be displayed in English unless they are explicitly
       
  6691     translated.
       
  6692 
       
  6693     If \a namespaceProcessing is true, the function QDomNode::prefix()
       
  6694     returns a string for all elements and attributes. It returns an
       
  6695     empty string if the element or attribute has no prefix.
       
  6696 
       
  6697     Text nodes consisting only of whitespace are stripped and won't
       
  6698     appear in the QDomDocument. If this behavior is not desired,
       
  6699     one can use the setContent() overload that allows a QXmlReader to be
       
  6700     supplied.
       
  6701 
       
  6702     If \a namespaceProcessing is false, the functions
       
  6703     QDomNode::prefix(), QDomNode::localName() and
       
  6704     QDomNode::namespaceURI() return an empty string.
       
  6705 
       
  6706     Entity references are handled as follows:
       
  6707     \list
       
  6708     \o References to internal general entities and character entities occurring in the
       
  6709         content are included. The result is a QDomText node with the references replaced
       
  6710         by their corresponding entity values.
       
  6711     \o References to parameter entities occurring in the internal subset are included.
       
  6712         The result is a QDomDocumentType node which contains entity and notation declarations
       
  6713         with the references replaced by their corresponding entity values.
       
  6714     \o Any general parsed entity reference which is not defined in the internal subset and
       
  6715         which occurs in the content is represented as a QDomEntityReference node.
       
  6716     \o Any parsed entity reference which is not defined in the internal subset and which
       
  6717         occurs outside of the content is replaced with an empty string.
       
  6718     \o Any unparsed entity reference is replaced with an empty string.
       
  6719     \endlist
       
  6720 
       
  6721     \sa QDomNode::namespaceURI() QDomNode::localName()
       
  6722     QDomNode::prefix() QString::isNull() QString::isEmpty()
       
  6723 */
       
  6724 bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6725 {
       
  6726     if (!impl)
       
  6727         impl = new QDomDocumentPrivate();
       
  6728     QBuffer buf;
       
  6729     buf.setData(data);
       
  6730     QXmlInputSource source(&buf);
       
  6731     return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn);
       
  6732 }
       
  6733 
       
  6734 /*!
       
  6735     \overload
       
  6736 
       
  6737     This function reads the XML document from the IO device \a dev, returning
       
  6738     true if the content was successfully parsed; otherwise returns false.
       
  6739 */
       
  6740 bool QDomDocument::setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6741 {
       
  6742     if (!impl)
       
  6743         impl = new QDomDocumentPrivate();
       
  6744     QXmlInputSource source(dev);
       
  6745     return IMPL->setContent(&source, namespaceProcessing, errorMsg, errorLine, errorColumn);
       
  6746 }
       
  6747 
       
  6748 /*!
       
  6749     \overload
       
  6750     \since 4.5
       
  6751 
       
  6752     This function reads the XML document from the QXmlInputSource \a source,
       
  6753     returning true if the content was successfully parsed; otherwise returns false.
       
  6754 
       
  6755 */
       
  6756 bool QDomDocument::setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6757 {
       
  6758     if (!impl)
       
  6759         impl = new QDomDocumentPrivate();
       
  6760     QXmlSimpleReader reader;
       
  6761     initializeReader(reader, namespaceProcessing);
       
  6762     return IMPL->setContent(source, &reader, errorMsg, errorLine, errorColumn);
       
  6763 }
       
  6764 
       
  6765 /*!
       
  6766     \overload
       
  6767 
       
  6768     This function reads the XML document from the string \a text, returning
       
  6769     true if the content was successfully parsed; otherwise returns false.
       
  6770     Since \a text is already a Unicode string, no encoding detection
       
  6771     is performed.
       
  6772 
       
  6773     No namespace processing is performed either.
       
  6774 */
       
  6775 bool QDomDocument::setContent(const QString& text, QString *errorMsg, int *errorLine, int *errorColumn)
       
  6776 {
       
  6777     return setContent(text, false, errorMsg, errorLine, errorColumn);
       
  6778 }
       
  6779 
       
  6780 /*!
       
  6781     \overload
       
  6782 
       
  6783     This function reads the XML document from the byte array \a buffer,
       
  6784     returning true if the content was successfully parsed; otherwise returns
       
  6785     false.
       
  6786 
       
  6787     No namespace processing is performed.
       
  6788 */
       
  6789 bool QDomDocument::setContent(const QByteArray& buffer, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6790 {
       
  6791     return setContent(buffer, false, errorMsg, errorLine, errorColumn);
       
  6792 }
       
  6793 
       
  6794 /*!
       
  6795     \overload
       
  6796 
       
  6797     This function reads the XML document from the IO device \a dev, returning
       
  6798     true if the content was successfully parsed; otherwise returns false.
       
  6799 
       
  6800     No namespace processing is performed.
       
  6801 */
       
  6802 bool QDomDocument::setContent(QIODevice* dev, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6803 {
       
  6804     return setContent(dev, false, errorMsg, errorLine, errorColumn);
       
  6805 }
       
  6806 
       
  6807 /*!
       
  6808     \overload
       
  6809 
       
  6810     This function reads the XML document from the QXmlInputSource \a source and
       
  6811     parses it with the QXmlReader \a reader, returning true if the content was
       
  6812     successfully parsed; otherwise returns false.
       
  6813 
       
  6814     This function doesn't change the features of the \a reader. If you want to
       
  6815     use certain features for parsing you can use this function to set up the
       
  6816     reader appropriately.
       
  6817 
       
  6818     \sa QXmlSimpleReader
       
  6819 */
       
  6820 bool QDomDocument::setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn )
       
  6821 {
       
  6822     if (!impl)
       
  6823         impl = new QDomDocumentPrivate();
       
  6824     return IMPL->setContent(source, reader, errorMsg, errorLine, errorColumn);
       
  6825 }
       
  6826 
       
  6827 /*!
       
  6828     Converts the parsed document back to its textual representation.
       
  6829 
       
  6830     This function uses \a indent as the amount of space to indent
       
  6831     subelements.
       
  6832 
       
  6833     If \a indent is -1, no whitespace at all is added.
       
  6834 */
       
  6835 QString QDomDocument::toString(int indent) const
       
  6836 {
       
  6837     QString str;
       
  6838     QTextStream s(&str, QIODevice::WriteOnly);
       
  6839     save(s, indent);
       
  6840     return str;
       
  6841 }
       
  6842 
       
  6843 /*!
       
  6844     Converts the parsed document back to its textual representation
       
  6845     and returns a QByteArray containing the data encoded as UTF-8.
       
  6846 
       
  6847     This function uses \a indent as the amount of space to indent
       
  6848     subelements.
       
  6849 
       
  6850     \sa toString()
       
  6851 */
       
  6852 QByteArray QDomDocument::toByteArray(int indent) const
       
  6853 {
       
  6854     // ### if there is an encoding specified in the xml declaration, this
       
  6855     // encoding declaration should be changed to utf8
       
  6856     return toString(indent).toUtf8();
       
  6857 }
       
  6858 
       
  6859 
       
  6860 /*!
       
  6861     Returns the document type of this document.
       
  6862 */
       
  6863 QDomDocumentType QDomDocument::doctype() const
       
  6864 {
       
  6865     if (!impl)
       
  6866         return QDomDocumentType();
       
  6867     return QDomDocumentType(IMPL->doctype());
       
  6868 }
       
  6869 
       
  6870 /*!
       
  6871     Returns a QDomImplementation object.
       
  6872 */
       
  6873 QDomImplementation QDomDocument::implementation() const
       
  6874 {
       
  6875     if (!impl)
       
  6876         return QDomImplementation();
       
  6877     return QDomImplementation(IMPL->implementation());
       
  6878 }
       
  6879 
       
  6880 /*!
       
  6881     Returns the root element of the document.
       
  6882 */
       
  6883 QDomElement QDomDocument::documentElement() const
       
  6884 {
       
  6885     if (!impl)
       
  6886         return QDomElement();
       
  6887     return QDomElement(IMPL->documentElement());
       
  6888 }
       
  6889 
       
  6890 /*!
       
  6891     Creates a new element called \a tagName that can be inserted into
       
  6892     the DOM tree, e.g. using QDomNode::appendChild().
       
  6893 
       
  6894     If \a tagName is not a valid XML name, the behavior of this function is governed
       
  6895     by QDomImplementation::InvalidDataPolicy.
       
  6896 
       
  6897     \sa createElementNS() QDomNode::appendChild() QDomNode::insertBefore()
       
  6898     QDomNode::insertAfter()
       
  6899 */
       
  6900 QDomElement QDomDocument::createElement(const QString& tagName)
       
  6901 {
       
  6902     if (!impl)
       
  6903         impl = new QDomDocumentPrivate();
       
  6904     return QDomElement(IMPL->createElement(tagName));
       
  6905 }
       
  6906 
       
  6907 /*!
       
  6908     Creates a new document fragment, that can be used to hold parts of
       
  6909     the document, e.g. when doing complex manipulations of the
       
  6910     document tree.
       
  6911 */
       
  6912 QDomDocumentFragment QDomDocument::createDocumentFragment()
       
  6913 {
       
  6914     if (!impl)
       
  6915         impl = new QDomDocumentPrivate();
       
  6916     return QDomDocumentFragment(IMPL->createDocumentFragment());
       
  6917 }
       
  6918 
       
  6919 /*!
       
  6920     Creates a text node for the string \a value that can be inserted
       
  6921     into the document tree, e.g. using QDomNode::appendChild().
       
  6922 
       
  6923     If \a value contains characters which cannot be stored as character
       
  6924     data of an XML document (even in the form of character references), the
       
  6925     behavior of this function is governed by QDomImplementation::InvalidDataPolicy.
       
  6926 
       
  6927     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6928 */
       
  6929 QDomText QDomDocument::createTextNode(const QString& value)
       
  6930 {
       
  6931     if (!impl)
       
  6932         impl = new QDomDocumentPrivate();
       
  6933     return QDomText(IMPL->createTextNode(value));
       
  6934 }
       
  6935 
       
  6936 /*!
       
  6937     Creates a new comment for the string \a value that can be inserted
       
  6938     into the document, e.g. using QDomNode::appendChild().
       
  6939 
       
  6940     If \a value contains characters which cannot be stored in an XML comment,
       
  6941     the behavior of this function is governed by QDomImplementation::InvalidDataPolicy.
       
  6942 
       
  6943     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6944 */
       
  6945 QDomComment QDomDocument::createComment(const QString& value)
       
  6946 {
       
  6947     if (!impl)
       
  6948         impl = new QDomDocumentPrivate();
       
  6949     return QDomComment(IMPL->createComment(value));
       
  6950 }
       
  6951 
       
  6952 /*!
       
  6953     Creates a new CDATA section for the string \a value that can be
       
  6954     inserted into the document, e.g. using QDomNode::appendChild().
       
  6955 
       
  6956     If \a value contains characters which cannot be stored in a CDATA section,
       
  6957     the behavior of this function is governed by
       
  6958     QDomImplementation::InvalidDataPolicy.
       
  6959 
       
  6960     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6961 */
       
  6962 QDomCDATASection QDomDocument::createCDATASection(const QString& value)
       
  6963 {
       
  6964     if (!impl)
       
  6965         impl = new QDomDocumentPrivate();
       
  6966     return QDomCDATASection(IMPL->createCDATASection(value));
       
  6967 }
       
  6968 
       
  6969 /*!
       
  6970     Creates a new processing instruction that can be inserted into the
       
  6971     document, e.g. using QDomNode::appendChild(). This function sets
       
  6972     the target for the processing instruction to \a target and the
       
  6973     data to \a data.
       
  6974 
       
  6975     If \a target is not a valid XML name, or data if contains characters which cannot
       
  6976     appear in a processing instruction, the behavior of this function is governed by
       
  6977     QDomImplementation::InvalidDataPolicy.
       
  6978 
       
  6979     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  6980 */
       
  6981 QDomProcessingInstruction QDomDocument::createProcessingInstruction(const QString& target,
       
  6982                                                                     const QString& data)
       
  6983 {
       
  6984     if (!impl)
       
  6985         impl = new QDomDocumentPrivate();
       
  6986     return QDomProcessingInstruction(IMPL->createProcessingInstruction(target, data));
       
  6987 }
       
  6988 
       
  6989 
       
  6990 /*!
       
  6991     Creates a new attribute called \a name that can be inserted into
       
  6992     an element, e.g. using QDomElement::setAttributeNode().
       
  6993 
       
  6994     If \a name is not a valid XML name, the behavior of this function is governed by
       
  6995     QDomImplementation::InvalidDataPolicy.
       
  6996 
       
  6997     \sa createAttributeNS()
       
  6998 */
       
  6999 QDomAttr QDomDocument::createAttribute(const QString& name)
       
  7000 {
       
  7001     if (!impl)
       
  7002         impl = new QDomDocumentPrivate();
       
  7003     return QDomAttr(IMPL->createAttribute(name));
       
  7004 }
       
  7005 
       
  7006 /*!
       
  7007     Creates a new entity reference called \a name that can be inserted
       
  7008     into the document, e.g. using QDomNode::appendChild().
       
  7009 
       
  7010     If \a name is not a valid XML name, the behavior of this function is governed by
       
  7011     QDomImplementation::InvalidDataPolicy.
       
  7012 
       
  7013     \sa QDomNode::appendChild() QDomNode::insertBefore() QDomNode::insertAfter()
       
  7014 */
       
  7015 QDomEntityReference QDomDocument::createEntityReference(const QString& name)
       
  7016 {
       
  7017     if (!impl)
       
  7018         impl = new QDomDocumentPrivate();
       
  7019     return QDomEntityReference(IMPL->createEntityReference(name));
       
  7020 }
       
  7021 
       
  7022 /*!
       
  7023     Returns a QDomNodeList, that contains all the elements in the
       
  7024     document with the name \a tagname. The order of the node list is
       
  7025     the order they are encountered in a preorder traversal of the
       
  7026     element tree.
       
  7027 
       
  7028     \sa elementsByTagNameNS() QDomElement::elementsByTagName()
       
  7029 */
       
  7030 QDomNodeList QDomDocument::elementsByTagName(const QString& tagname) const
       
  7031 {
       
  7032     return QDomNodeList(new QDomNodeListPrivate(impl, tagname));
       
  7033 }
       
  7034 
       
  7035 /*!
       
  7036     Imports the node \a importedNode from another document to this
       
  7037     document. \a importedNode remains in the original document; this
       
  7038     function creates a copy that can be used within this document.
       
  7039 
       
  7040     This function returns the imported node that belongs to this
       
  7041     document. The returned node has no parent. It is not possible to
       
  7042     import QDomDocument and QDomDocumentType nodes. In those cases
       
  7043     this function returns a \link QDomNode::isNull() null node\endlink.
       
  7044 
       
  7045     If \a deep is true, this function imports not only the node \a
       
  7046     importedNode but its whole subtree; if it is false, only the \a
       
  7047     importedNode is imported. The argument \a deep has no effect on
       
  7048     QDomAttr and QDomEntityReference nodes, since the descendants of
       
  7049     QDomAttr nodes are always imported and those of
       
  7050     QDomEntityReference nodes are never imported.
       
  7051 
       
  7052     The behavior of this function is slightly different depending on
       
  7053     the node types:
       
  7054     \table
       
  7055     \header \i Node Type \i Behavior
       
  7056     \row \i QDomAttr
       
  7057          \i The owner element is set to 0 and the specified flag is
       
  7058             set to true in the generated attribute. The whole subtree
       
  7059             of \a importedNode is always imported for attribute nodes:
       
  7060             \a deep has no effect.
       
  7061     \row \i QDomDocument
       
  7062          \i Document nodes cannot be imported.
       
  7063     \row \i QDomDocumentFragment
       
  7064          \i If \a deep is true, this function imports the whole
       
  7065             document fragment; otherwise it only generates an empty
       
  7066             document fragment.
       
  7067     \row \i QDomDocumentType
       
  7068          \i Document type nodes cannot be imported.
       
  7069     \row \i QDomElement
       
  7070          \i Attributes for which QDomAttr::specified() is true are
       
  7071             also imported, other attributes are not imported. If \a
       
  7072             deep is true, this function also imports the subtree of \a
       
  7073             importedNode; otherwise it imports only the element node
       
  7074             (and some attributes, see above).
       
  7075     \row \i QDomEntity
       
  7076          \i Entity nodes can be imported, but at the moment there is
       
  7077             no way to use them since the document type is read-only in
       
  7078             DOM level 2.
       
  7079     \row \i QDomEntityReference
       
  7080          \i Descendants of entity reference nodes are never imported:
       
  7081             \a deep has no effect.
       
  7082     \row \i QDomNotation
       
  7083          \i Notation nodes can be imported, but at the moment there is
       
  7084             no way to use them since the document type is read-only in
       
  7085             DOM level 2.
       
  7086     \row \i QDomProcessingInstruction
       
  7087          \i The target and value of the processing instruction is
       
  7088             copied to the new node.
       
  7089     \row \i QDomText
       
  7090          \i The text is copied to the new node.
       
  7091     \row \i QDomCDATASection
       
  7092          \i The text is copied to the new node.
       
  7093     \row \i QDomComment
       
  7094          \i The text is copied to the new node.
       
  7095     \endtable
       
  7096 
       
  7097     \sa QDomElement::setAttribute() QDomNode::insertBefore()
       
  7098         QDomNode::insertAfter() QDomNode::replaceChild() QDomNode::removeChild()
       
  7099         QDomNode::appendChild()
       
  7100 */
       
  7101 QDomNode QDomDocument::importNode(const QDomNode& importedNode, bool deep)
       
  7102 {
       
  7103     if (!impl)
       
  7104         impl = new QDomDocumentPrivate();
       
  7105     return QDomNode(IMPL->importNode(importedNode.impl, deep));
       
  7106 }
       
  7107 
       
  7108 /*!
       
  7109     Creates a new element with namespace support that can be inserted
       
  7110     into the DOM tree. The name of the element is \a qName and the
       
  7111     namespace URI is \a nsURI. This function also sets
       
  7112     QDomNode::prefix() and QDomNode::localName() to appropriate values
       
  7113     (depending on \a qName).
       
  7114 
       
  7115     If \a qName is an empty string, returns a null element regardless of
       
  7116     whether the invalid data policy is set.
       
  7117 
       
  7118     \sa createElement()
       
  7119 */
       
  7120 QDomElement QDomDocument::createElementNS(const QString& nsURI, const QString& qName)
       
  7121 {
       
  7122     if (!impl)
       
  7123         impl = new QDomDocumentPrivate();
       
  7124     return QDomElement(IMPL->createElementNS(nsURI, qName));
       
  7125 }
       
  7126 
       
  7127 /*!
       
  7128     Creates a new attribute with namespace support that can be
       
  7129     inserted into an element. The name of the attribute is \a qName
       
  7130     and the namespace URI is \a nsURI. This function also sets
       
  7131     QDomNode::prefix() and QDomNode::localName() to appropriate values
       
  7132     (depending on \a qName).
       
  7133 
       
  7134     If \a qName is not a valid XML name, the behavior of this function is governed by
       
  7135     QDomImplementation::InvalidDataPolicy.
       
  7136 
       
  7137     \sa createAttribute()
       
  7138 */
       
  7139 QDomAttr QDomDocument::createAttributeNS(const QString& nsURI, const QString& qName)
       
  7140 {
       
  7141     if (!impl)
       
  7142         impl = new QDomDocumentPrivate();
       
  7143     return QDomAttr(IMPL->createAttributeNS(nsURI, qName));
       
  7144 }
       
  7145 
       
  7146 /*!
       
  7147     Returns a QDomNodeList that contains all the elements in the
       
  7148     document with the local name \a localName and a namespace URI of
       
  7149     \a nsURI. The order of the node list is the order they are
       
  7150     encountered in a preorder traversal of the element tree.
       
  7151 
       
  7152     \sa elementsByTagName() QDomElement::elementsByTagNameNS()
       
  7153 */
       
  7154 QDomNodeList QDomDocument::elementsByTagNameNS(const QString& nsURI, const QString& localName)
       
  7155 {
       
  7156     return QDomNodeList(new QDomNodeListPrivate(impl, nsURI, localName));
       
  7157 }
       
  7158 
       
  7159 /*!
       
  7160     Returns the element whose ID is equal to \a elementId. If no
       
  7161     element with the ID was found, this function returns a \link
       
  7162     QDomNode::isNull() null element\endlink.
       
  7163 
       
  7164     Since the QDomClasses do not know which attributes are element
       
  7165     IDs, this function returns always a \link QDomNode::isNull() null
       
  7166     element\endlink. This may change in a future version.
       
  7167 */
       
  7168 QDomElement QDomDocument::elementById(const QString& /*elementId*/)
       
  7169 {
       
  7170     qWarning("elementById() is not implemented and will always return a null node.");
       
  7171     return QDomElement();
       
  7172 }
       
  7173 
       
  7174 /*!
       
  7175     \fn QDomNode::NodeType QDomDocument::nodeType() const
       
  7176 
       
  7177     Returns \c DocumentNode.
       
  7178 */
       
  7179 
       
  7180 #undef IMPL
       
  7181 
       
  7182 /**************************************************************
       
  7183  *
       
  7184  * Node casting functions
       
  7185  *
       
  7186  **************************************************************/
       
  7187 
       
  7188 /*!
       
  7189     Converts a QDomNode into a QDomAttr. If the node is not an
       
  7190     attribute, the returned object will be \link QDomNode::isNull()
       
  7191     null\endlink.
       
  7192 
       
  7193     \sa isAttr()
       
  7194 */
       
  7195 QDomAttr QDomNode::toAttr() const
       
  7196 {
       
  7197     if (impl && impl->isAttr())
       
  7198         return QDomAttr(((QDomAttrPrivate*)impl));
       
  7199     return QDomAttr();
       
  7200 }
       
  7201 
       
  7202 /*!
       
  7203     Converts a QDomNode into a QDomCDATASection. If the node is not a
       
  7204     CDATA section, the returned object will be \link
       
  7205     QDomNode::isNull() null\endlink.
       
  7206 
       
  7207     \sa isCDATASection()
       
  7208 */
       
  7209 QDomCDATASection QDomNode::toCDATASection() const
       
  7210 {
       
  7211     if (impl && impl->isCDATASection())
       
  7212         return QDomCDATASection(((QDomCDATASectionPrivate*)impl));
       
  7213     return QDomCDATASection();
       
  7214 }
       
  7215 
       
  7216 /*!
       
  7217     Converts a QDomNode into a QDomDocumentFragment. If the node is
       
  7218     not a document fragment the returned object will be \link
       
  7219     QDomNode::isNull() null\endlink.
       
  7220 
       
  7221     \sa isDocumentFragment()
       
  7222 */
       
  7223 QDomDocumentFragment QDomNode::toDocumentFragment() const
       
  7224 {
       
  7225     if (impl && impl->isDocumentFragment())
       
  7226         return QDomDocumentFragment(((QDomDocumentFragmentPrivate*)impl));
       
  7227     return QDomDocumentFragment();
       
  7228 }
       
  7229 
       
  7230 /*!
       
  7231     Converts a QDomNode into a QDomDocument. If the node is not a
       
  7232     document the returned object will be \link QDomNode::isNull()
       
  7233     null\endlink.
       
  7234 
       
  7235     \sa isDocument()
       
  7236 */
       
  7237 QDomDocument QDomNode::toDocument() const
       
  7238 {
       
  7239     if (impl && impl->isDocument())
       
  7240         return QDomDocument(((QDomDocumentPrivate*)impl));
       
  7241     return QDomDocument();
       
  7242 }
       
  7243 
       
  7244 /*!
       
  7245     Converts a QDomNode into a QDomDocumentType. If the node is not a
       
  7246     document type the returned object will be \link QDomNode::isNull()
       
  7247     null\endlink.
       
  7248 
       
  7249     \sa isDocumentType()
       
  7250 */
       
  7251 QDomDocumentType QDomNode::toDocumentType() const
       
  7252 {
       
  7253     if (impl && impl->isDocumentType())
       
  7254         return QDomDocumentType(((QDomDocumentTypePrivate*)impl));
       
  7255     return QDomDocumentType();
       
  7256 }
       
  7257 
       
  7258 /*!
       
  7259     Converts a QDomNode into a QDomElement. If the node is not an
       
  7260     element the returned object will be \link QDomNode::isNull()
       
  7261     null\endlink.
       
  7262 
       
  7263     \sa isElement()
       
  7264 */
       
  7265 QDomElement QDomNode::toElement() const
       
  7266 {
       
  7267     if (impl && impl->isElement())
       
  7268         return QDomElement(((QDomElementPrivate*)impl));
       
  7269     return QDomElement();
       
  7270 }
       
  7271 
       
  7272 /*!
       
  7273     Converts a QDomNode into a QDomEntityReference. If the node is not
       
  7274     an entity reference, the returned object will be \link
       
  7275     QDomNode::isNull() null\endlink.
       
  7276 
       
  7277     \sa isEntityReference()
       
  7278 */
       
  7279 QDomEntityReference QDomNode::toEntityReference() const
       
  7280 {
       
  7281     if (impl && impl->isEntityReference())
       
  7282         return QDomEntityReference(((QDomEntityReferencePrivate*)impl));
       
  7283     return QDomEntityReference();
       
  7284 }
       
  7285 
       
  7286 /*!
       
  7287     Converts a QDomNode into a QDomText. If the node is not a text,
       
  7288     the returned object will be \link QDomNode::isNull() null\endlink.
       
  7289 
       
  7290     \sa isText()
       
  7291 */
       
  7292 QDomText QDomNode::toText() const
       
  7293 {
       
  7294     if (impl && impl->isText())
       
  7295         return QDomText(((QDomTextPrivate*)impl));
       
  7296     return QDomText();
       
  7297 }
       
  7298 
       
  7299 /*!
       
  7300     Converts a QDomNode into a QDomEntity. If the node is not an
       
  7301     entity the returned object will be \link QDomNode::isNull()
       
  7302     null\endlink.
       
  7303 
       
  7304     \sa isEntity()
       
  7305 */
       
  7306 QDomEntity QDomNode::toEntity() const
       
  7307 {
       
  7308     if (impl && impl->isEntity())
       
  7309         return QDomEntity(((QDomEntityPrivate*)impl));
       
  7310     return QDomEntity();
       
  7311 }
       
  7312 
       
  7313 /*!
       
  7314     Converts a QDomNode into a QDomNotation. If the node is not a
       
  7315     notation the returned object will be \link QDomNode::isNull()
       
  7316     null\endlink.
       
  7317 
       
  7318     \sa isNotation()
       
  7319 */
       
  7320 QDomNotation QDomNode::toNotation() const
       
  7321 {
       
  7322     if (impl && impl->isNotation())
       
  7323         return QDomNotation(((QDomNotationPrivate*)impl));
       
  7324     return QDomNotation();
       
  7325 }
       
  7326 
       
  7327 /*!
       
  7328     Converts a QDomNode into a QDomProcessingInstruction. If the node
       
  7329     is not a processing instruction the returned object will be \link
       
  7330     QDomNode::isNull() null\endlink.
       
  7331 
       
  7332     \sa isProcessingInstruction()
       
  7333 */
       
  7334 QDomProcessingInstruction QDomNode::toProcessingInstruction() const
       
  7335 {
       
  7336     if (impl && impl->isProcessingInstruction())
       
  7337         return QDomProcessingInstruction(((QDomProcessingInstructionPrivate*)impl));
       
  7338     return QDomProcessingInstruction();
       
  7339 }
       
  7340 
       
  7341 /*!
       
  7342     Converts a QDomNode into a QDomCharacterData. If the node is not a
       
  7343     character data node the returned object will be \link
       
  7344     QDomNode::isNull() null\endlink.
       
  7345 
       
  7346     \sa isCharacterData()
       
  7347 */
       
  7348 QDomCharacterData QDomNode::toCharacterData() const
       
  7349 {
       
  7350     if (impl && impl->isCharacterData())
       
  7351         return QDomCharacterData(((QDomCharacterDataPrivate*)impl));
       
  7352     return QDomCharacterData();
       
  7353 }
       
  7354 
       
  7355 /*!
       
  7356     Converts a QDomNode into a QDomComment. If the node is not a
       
  7357     comment the returned object will be \link QDomNode::isNull()
       
  7358     null\endlink.
       
  7359 
       
  7360     \sa isComment()
       
  7361 */
       
  7362 QDomComment QDomNode::toComment() const
       
  7363 {
       
  7364     if (impl && impl->isComment())
       
  7365         return QDomComment(((QDomCommentPrivate*)impl));
       
  7366     return QDomComment();
       
  7367 }
       
  7368 
       
  7369 /**************************************************************
       
  7370  *
       
  7371  * QDomHandler
       
  7372  *
       
  7373  **************************************************************/
       
  7374 
       
  7375 QDomHandler::QDomHandler(QDomDocumentPrivate* adoc, bool namespaceProcessing)
       
  7376     : errorLine(0), errorColumn(0), doc(adoc), node(adoc), cdata(false),
       
  7377         nsProcessing(namespaceProcessing), locator(0)
       
  7378 {
       
  7379 }
       
  7380 
       
  7381 QDomHandler::~QDomHandler()
       
  7382 {
       
  7383 }
       
  7384 
       
  7385 bool QDomHandler::endDocument()
       
  7386 {
       
  7387     // ### is this really necessary? (rms)
       
  7388     if (node != doc)
       
  7389         return false;
       
  7390     return true;
       
  7391 }
       
  7392 
       
  7393 bool QDomHandler::startDTD(const QString& name, const QString& publicId, const QString& systemId)
       
  7394 {
       
  7395     doc->doctype()->name = name;
       
  7396     doc->doctype()->publicId = publicId;
       
  7397     doc->doctype()->systemId = systemId;
       
  7398     return true;
       
  7399 }
       
  7400 
       
  7401 bool QDomHandler::startElement(const QString& nsURI, const QString&, const QString& qName, const QXmlAttributes& atts)
       
  7402 {
       
  7403     // tag name
       
  7404     QDomNodePrivate* n;
       
  7405     if (nsProcessing) {
       
  7406         n = doc->createElementNS(nsURI, qName);
       
  7407     } else {
       
  7408         n = doc->createElement(qName);
       
  7409     }
       
  7410 
       
  7411     if (n)
       
  7412         n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7413 
       
  7414     node->appendChild(n);
       
  7415     node = n;
       
  7416 
       
  7417     // attributes
       
  7418     for (int i=0; i<atts.length(); i++)
       
  7419     {
       
  7420         if (nsProcessing) {
       
  7421             ((QDomElementPrivate*)node)->setAttributeNS(atts.uri(i), atts.qName(i), atts.value(i));
       
  7422         } else {
       
  7423             ((QDomElementPrivate*)node)->setAttribute(atts.qName(i), atts.value(i));
       
  7424         }
       
  7425     }
       
  7426 
       
  7427     return true;
       
  7428 }
       
  7429 
       
  7430 bool QDomHandler::endElement(const QString&, const QString&, const QString&)
       
  7431 {
       
  7432     if (!node || node == doc)
       
  7433         return false;
       
  7434     node = node->parent();
       
  7435 
       
  7436     return true;
       
  7437 }
       
  7438 
       
  7439 bool QDomHandler::characters(const QString&  ch)
       
  7440 {
       
  7441     // No text as child of some document
       
  7442     if (node == doc)
       
  7443         return false;
       
  7444 
       
  7445     QScopedPointer<QDomNodePrivate> n;
       
  7446     if (cdata) {
       
  7447         n.reset(doc->createCDATASection(ch));
       
  7448     } else if (!entityName.isEmpty()) {
       
  7449         QScopedPointer<QDomEntityPrivate> e(new QDomEntityPrivate(doc, 0, entityName,
       
  7450                 QString(), QString(), QString()));
       
  7451         e->value = ch;
       
  7452         doc->doctype()->appendChild(e.data());
       
  7453         e.take();
       
  7454         n.reset(doc->createEntityReference(entityName));
       
  7455     } else {
       
  7456         n.reset(doc->createTextNode(ch));
       
  7457     }
       
  7458     n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7459     node->appendChild(n.data());
       
  7460     n.take();
       
  7461 
       
  7462     return true;
       
  7463 }
       
  7464 
       
  7465 bool QDomHandler::processingInstruction(const QString& target, const QString& data)
       
  7466 {
       
  7467     QDomNodePrivate *n;
       
  7468     n = doc->createProcessingInstruction(target, data);
       
  7469     if (n) {
       
  7470         n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7471         node->appendChild(n);
       
  7472         return true;
       
  7473     }
       
  7474     else
       
  7475         return false;
       
  7476 }
       
  7477 
       
  7478 extern bool qt_xml_skipped_entity_in_content;
       
  7479 bool QDomHandler::skippedEntity(const QString& name)
       
  7480 {
       
  7481     // we can only handle inserting entity references into content
       
  7482     if (!qt_xml_skipped_entity_in_content)
       
  7483         return true;
       
  7484 
       
  7485     QDomNodePrivate *n = doc->createEntityReference(name);
       
  7486     n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7487     node->appendChild(n);
       
  7488     return true;
       
  7489 }
       
  7490 
       
  7491 bool QDomHandler::fatalError(const QXmlParseException& exception)
       
  7492 {
       
  7493     errorMsg = exception.message();
       
  7494     errorLine =  exception.lineNumber();
       
  7495     errorColumn =  exception.columnNumber();
       
  7496     return QXmlDefaultHandler::fatalError(exception);
       
  7497 }
       
  7498 
       
  7499 bool QDomHandler::startCDATA()
       
  7500 {
       
  7501     cdata = true;
       
  7502     return true;
       
  7503 }
       
  7504 
       
  7505 bool QDomHandler::endCDATA()
       
  7506 {
       
  7507     cdata = false;
       
  7508     return true;
       
  7509 }
       
  7510 
       
  7511 bool QDomHandler::startEntity(const QString &name)
       
  7512 {
       
  7513     entityName = name;
       
  7514     return true;
       
  7515 }
       
  7516 
       
  7517 bool QDomHandler::endEntity(const QString &)
       
  7518 {
       
  7519     entityName.clear();
       
  7520     return true;
       
  7521 }
       
  7522 
       
  7523 bool QDomHandler::comment(const QString& ch)
       
  7524 {
       
  7525     QDomNodePrivate *n;
       
  7526     n = doc->createComment(ch);
       
  7527     n->setLocation(locator->lineNumber(), locator->columnNumber());
       
  7528     node->appendChild(n);
       
  7529     return true;
       
  7530 }
       
  7531 
       
  7532 bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName)
       
  7533 {
       
  7534     QDomEntityPrivate* e = new QDomEntityPrivate(doc, 0, name,
       
  7535             publicId, systemId, notationName);
       
  7536     doc->doctype()->appendChild(e);
       
  7537     return true;
       
  7538 }
       
  7539 
       
  7540 bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId)
       
  7541 {
       
  7542     return unparsedEntityDecl(name, publicId, systemId, QString());
       
  7543 }
       
  7544 
       
  7545 bool QDomHandler::notationDecl(const QString & name, const QString & publicId, const QString & systemId)
       
  7546 {
       
  7547     QDomNotationPrivate* n = new QDomNotationPrivate(doc, 0, name, publicId, systemId);
       
  7548     doc->doctype()->appendChild(n);
       
  7549     return true;
       
  7550 }
       
  7551 
       
  7552 void QDomHandler::setDocumentLocator(QXmlLocator *locator)
       
  7553 {
       
  7554     this->locator = locator;
       
  7555 }
       
  7556 
       
  7557 QT_END_NAMESPACE
       
  7558 
       
  7559 #endif // QT_NO_DOM