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

source code of qtbase/src/xml/dom/qdom.cpp