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