~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/xml/qdom.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

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