Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/tinyxml/ticpp.h @ 739

Last change on this file since 739 was 739, checked in by landauf, 16 years ago

added TiCPP:

"'TiCPP' is short for the official name TinyXML++. It is a completely new interface to TinyXML that uses MANY of the C++ strengths. Templates, exceptions, and much better error handling."

website: http://code.google.com/p/ticpp/

File size: 46.6 KB
Line 
1/*
2http://code.google.com/p/ticpp/
3Copyright (c) 2006 Ryan Pusztai, Ryan Mulder
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of
6this software and associated documentation files (the "Software"), to deal in
7the Software without restriction, including without limitation the rights to
8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9the Software, and to permit persons to whom the Software is furnished to do so,
10subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21*/
22
23/**
24@copydoc ticpp
25@file
26@author         Ryan Pusztai
27@author         Ryan Mulder
28@date           04/11/2006
29
30@version        0.04a by edam@waxworlds.org: based Exception based on std::exception; added stream
31                                        << and >> support; added Document::Parse(); bug fix; improved THROW() macro.
32@version        0.04 Added NodeImp class. Also made all the classes inherit from NodeImp.
33@version        0.03 Added Declaration class
34@version        0.02 Added Element class
35@version        0.01 Added Exception class, Document class
36
37@todo add UNKNOWN support. See ticpp::NodeFactory.
38@todo add TYPECOUNT support. See ticpp::NodeFactory.
39@todo Add a quick reference
40*/
41#ifdef TIXML_USE_TICPP
42
43#ifndef TICPP_INCLUDED
44#define TICPP_INCLUDED
45
46#include "tinyxml.h"
47#include <sstream>
48#include <vector>
49#include <memory>
50#include <exception>
51
52/**
53@subpage ticpp is a TinyXML wrapper that uses a lot more C++ ideals.
54It throws exceptions, uses templates, is in its own name space, and
55<b>requires</b> STL (Standard Template Library). This is done to ease the use
56of getting values in and out of the xml.
57
58If you don't perfer to use some of the concepts just don't use it.
59It is just a wrapper that extends TinyXML. It doesn't actually change
60any of TinyXML.
61*/
62namespace ticpp
63{
64    /**
65        This is a ticpp exception class
66        */
67        class Exception : public std::exception
68        {
69        public:
70                /**
71                Construct an exception with a message
72                */
73                Exception( const std::string& details );
74                ~Exception() throw();
75
76                /// Override std::exception::what() to return m_details
77                const char* what() const throw();
78
79                std::string m_details; /**< Exception Details */
80        };
81
82        /**
83        This allows you to stream your exceptions in.
84        It will take care of the conversion     and throwing the exception.
85        */
86        #define TICPPTHROW( message )                                                                                   \
87        {                                                                                                                                               \
88                std::ostringstream full_message;                                                                        \
89                std::string file( __FILE__ );                                                                           \
90                file = file.substr( file.find_last_of( "\\/" ) + 1 );                           \
91                full_message << message << " <" << file << "@" << __LINE__ << ">";      \
92                throw Exception( full_message.str() );                                                          \
93        }
94
95        // Forward Declarations for Visitor, and others.
96        class Document;
97        class Element;
98        class Declaration;
99        class StylesheetReference;
100        class Text;
101        class Comment;
102        class Attribute;
103
104        /** Wrapper around TiXmlVisitor */
105        class Visitor : public TiXmlVisitor
106        {
107        public:
108                // Overload the TiXmlVisitor functions, wrap objects, call ticpp::Visitor functions
109                /// @internal
110                virtual bool VisitEnter( const TiXmlDocument& doc );
111                /// @internal
112                virtual bool VisitExit( const TiXmlDocument& doc );
113                /// @internal
114                virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
115                /// @internal
116                virtual bool VisitExit( const TiXmlElement& element );
117                /// @internal
118                virtual bool Visit( const TiXmlDeclaration& declaration );
119                /// @internal
120                virtual bool Visit( const TiXmlStylesheetReference& stylesheet );
121                /// @internal
122                virtual bool Visit( const TiXmlText& text );
123                /// @internal
124                virtual bool Visit( const TiXmlComment& comment );
125
126        public:
127                /// Visit a document.
128                virtual bool VisitEnter( const Document& /*doc*/ )                      { return true; }
129                /// Visit a document.
130                virtual bool VisitExit( const Document& /*doc*/ )                       { return true; }
131
132                /// Visit an element.
133                virtual bool VisitEnter( const Element& /*element*/, const Attribute* /*firstAttribute*/ )      { return true; }
134                /// Visit an element.
135                virtual bool VisitExit( const Element& /*element*/ )            { return true; }
136
137                /// Visit a declaration
138                virtual bool Visit( const Declaration& /*declaration*/ )        { return true; }
139                /// Visit a stylesheet reference
140                virtual bool Visit( const StylesheetReference& /*stylesheet*/ ) { return true; }
141                /// Visit a text node
142                virtual bool Visit( const Text& /*text*/ )                                      { return true; }
143                /// Visit a comment node
144                virtual bool Visit( const Comment& /*comment*/ )                        { return true; }
145        };
146
147        /** Wrapper around TiXmlBase */
148        class Base
149        {
150        public:
151
152                /**
153                Converts any class with a proper overload of the << opertor to a std::string
154                @param value The value to be converted
155                @throws Exception When value cannot be converted to a std::string
156                */
157                template < class T >
158                        std::string ToString( const T& value ) const
159                {
160                        std::stringstream convert;
161                        convert << value;
162                        if ( convert.fail() )
163                        {
164                                TICPPTHROW( "Could not convert value to text" );
165                        }
166                        return convert.str();
167                }
168
169                std::string ToString( const std::string& value ) const
170                {
171                        return value;
172                }
173
174                /**
175                Converts a std::string to any class with a proper overload of the >> opertor
176                @param temp                     The string to be converted
177                @param out      [OUT]   The container for the returned value
178                @throws Exception When temp cannot be converted to the target type
179                */
180                template < class T >
181                        void FromString( const std::string& temp, T* out ) const
182                {
183                        std::istringstream val( temp );
184                        val >> *out;
185
186                        if ( val.fail() )
187                        {
188                                TICPPTHROW( "Could not convert \"" << temp << "\" to target type" );
189                        }
190                }
191
192                /**
193                Specialization for std::string
194                */
195                void FromString( const std::string& temp, std::string* out ) const
196                {
197                        *out = temp;
198                }
199
200                /**
201                Return the position, in the original source file, of this node or attribute.
202                Wrapper around TiXmlBase::Row()
203                */
204                int Row() const
205                {
206                        return GetBasePointer()->Row();
207                }
208
209                /**
210                Return the position, in the original source file, of this node or attribute.
211                Wrapper around TiXmlBase::Row()
212                */
213                int Column() const
214                {
215                        return GetBasePointer()->Column();
216                }
217
218                /**
219                Destructor
220                */
221                virtual ~Base()
222                {
223                        DeleteSpawnedWrappers();
224                }
225
226        protected:
227                mutable TiCppRCImp* m_impRC;    /**< Holds status of internal TiXmlPointer - use this to determine if object has been deleted already */
228
229                mutable std::vector< Base* > m_spawnedWrappers; /**< Remember all wrappers that we've created with 'new' - ( e.g. NodeFactory, FirstChildElement, etc. )*/
230
231                /**
232                @internal
233                Updates the pointer to the reference counter to point at the counter in the new node.
234
235                @param node TiXmlBase containing the new reference counter
236                */
237                void SetImpRC( TiXmlBase* node )
238                {
239                        m_impRC = node->m_tiRC;
240                }
241
242                void ValidatePointer() const
243                {
244                        if ( m_impRC->IsNull() )
245                        {
246                                TICPPTHROW( "Internal TiXml Pointer is NULL" );
247                        }
248                }
249
250                /**
251                @internal
252                Delete all container objects we've spawned with 'new'.
253                */
254                void DeleteSpawnedWrappers()
255                {
256                        std::vector< Base* >::reverse_iterator wrapper;
257                        for ( wrapper = m_spawnedWrappers.rbegin(); wrapper != m_spawnedWrappers.rend(); ++wrapper )
258                        {
259                                delete *wrapper;
260                        }
261                        m_spawnedWrappers.clear();
262                }
263
264                /**
265                @internal
266                Get internal TiXmlBase*
267                */
268                virtual TiXmlBase* GetBasePointer() const = 0;
269        };
270
271        /**
272        Wrapper around TiXmlAttribute
273        */
274        class Attribute : public Base
275        {
276        private:
277                TiXmlAttribute* m_tiXmlPointer;
278                TiXmlBase* GetBasePointer() const
279                {
280                        ValidatePointer();
281                        return m_tiXmlPointer;
282                }
283
284        public:
285                /**
286                Construct an empty attribute.
287                */
288                Attribute();
289
290                /**
291                Construct an attribute with @a name and @a value
292
293                @param name The name of the attribute
294                @param value The value of the attribute
295                */
296                Attribute( const std::string& name, const std::string& value );
297
298                /**
299                @internal
300                Construct an attribute with the internal pointer
301
302                @param attribute The internal pointer
303                */
304                Attribute( TiXmlAttribute* attribute );
305
306                /**
307                Get the value of this attribute
308                Uses Base::FromString to convert TiXmlAttribute::ValueStr from a std::string,
309                and puts it in the passed pointer.
310
311                @param value [OUT] A pointer to fill with the value
312                */
313                template < class T >
314                        void GetValue( T* value ) const
315                {
316                        ValidatePointer();
317                        FromString( m_tiXmlPointer->ValueStr(), value );
318                }
319
320                /**
321                Get the value of this attribute.
322                Simple wrapper for TiXmlAttribute::ValueStr.
323
324                @see GetValue
325                */
326                std::string Value() const;
327
328                /**
329                Set the value of this node.
330                Uses Base::ToString to convert value to a std::string, then calls TiXmlAttribute::SetValue.
331
332                @param value The value to set
333                */
334                template < class T >
335                        void SetValue( const T& value )
336                {
337                        ValidatePointer();
338                        m_tiXmlPointer->SetValue( ToString( value ) );
339                }
340
341                /**
342                Get the value of this attribute
343                Uses Base::FromString to convert TiXmlAttribute::Name from a std::string,
344                and puts it in the passed pointer.
345
346                @param name [OUT] A pointer to fill with the name
347                */
348                template < class T >
349                        void GetName( T* name ) const
350                {
351                        ValidatePointer();
352                        FromString( m_tiXmlPointer->Name(), name );
353                }
354
355                /**
356                Get the value of this attribute.
357                Simple wrapper for TiXmlAttribute::Name.
358
359                @see GetName
360                */
361                std::string Name() const;
362
363                /**
364                Set the value of this attribute.
365                Uses Base::ToString to convert @a name to a std::string, then calls TiXmlAttribute::SetName.
366
367                @param name The name to set
368                */
369                template < class T >
370                        void SetName( const T& name )
371                {
372                        ValidatePointer();
373                        m_tiXmlPointer->SetName( ToString( name ) );
374                }
375
376                /**
377                @internal
378                Updates the reference count for the old and new pointers.
379                */
380                void operator=( const Attribute& copy );
381
382                /**
383                @internal
384                Updates the reference count for the old and new pointers.
385                */
386                Attribute( const Attribute& copy );
387
388                /*
389                Decrements reference count.
390                */
391                ~Attribute();
392
393                /**
394                Get the next sibling attribute in the DOM.
395                */
396                Attribute* Next( bool throwIfNoAttribute = true ) const;
397
398                /**
399                Get the previous sibling attribute in the DOM.
400                */
401                Attribute* Previous( bool throwIfNoAttribute = true ) const;
402
403                /**
404                @internal
405                Just for Iterator<>
406
407                @param next [OUT] The pointer to the next valid attribute
408                @return true if there is a next attribute, false if not
409                */
410                void IterateNext( const std::string&, Attribute** next ) const;
411
412                /**
413                @internal
414                Just for Iterator<>
415
416                @param previous [OUT] The pointer to the previous valid attribute
417                @return true if there is a previous attribute, false if not
418                */
419                void IteratePrevious( const std::string&, Attribute** previous ) const;
420
421                /**
422                All TinyXml classes can print themselves to a filestream.
423                */
424                virtual void Print( FILE* file, int depth ) const;
425
426        private:
427
428                /**
429                @internal
430                Sets the internal pointer.
431                Saves a copy of the pointer to the RC object.
432
433                @param newPointer TiXmlAttribute* to set.
434                */
435                void SetTiXmlPointer( TiXmlAttribute* newPointer );
436        };
437
438        /**
439        Wrapper around TiXmlNode
440        */
441        class Node : public Base
442        {
443        public:
444
445                /**
446                Get the value of this node
447                Uses Base::FromString to convert TiXmlNode::ValueStr from a std::string,
448                and puts it in the passed pointer.
449
450                @param value [OUT] A pointer to fill with the value
451                */
452                template < class T >
453                        void GetValue( T* value) const
454                {
455                        FromString( GetTiXmlPointer()->ValueStr(), value );
456                }
457
458                /**
459                Get the value of this node.
460                Simple wrapper for TiXmlNode::ValueStr.
461
462                @see GetValue
463                */
464                std::string Value() const;
465
466                /**
467                Set the value of this node.
468                Uses Base::ToString to convert value to a std::string, then calls TiXmlNode::SetValue.
469
470                @param value The value to set
471                */
472                template < class T >
473                        void SetValue( const T& value )
474                {
475                        GetTiXmlPointer()->SetValue( ToString( value ) );
476                }
477
478                /**
479                Clear all Nodes below this.
480                Simple wrapper for TiXmlNode::Clear.
481                */
482                void Clear();
483
484                /**
485                The Parent of this Node.
486                Simple wrapper for TiXmlNode::Parent.
487
488                @param throwIfNoParent [DEF] If true, throws when Parent = NULL.
489                @return The parent of this node, NULL if there is no Parent.
490                @throws Exception When throwIfNoParent is true, and TiXmlNode::Parent returns Null.
491                */
492                Node* Parent( bool throwIfNoParent = true ) const;
493
494                /**
495                The first child of this node.
496
497                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
498                @return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
499                @throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChild returns Null.
500
501                @see TiXmlNode::FirstChild
502                */
503                Node* FirstChild( bool throwIfNoChildren = true ) const;
504
505                /**
506                @internal
507                The first child of this node with the matching @a value.
508
509                @overload
510                @param value                            Value to match.
511                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
512
513                @see FirstChild( bool throwIfNoChildren = true )
514                */
515                Node* FirstChild( const char* value, bool throwIfNoChildren = true ) const;
516
517                /**
518                The first child of this node with the matching @a value.
519
520                @overload
521                @param value                            Value to match.
522                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
523
524                @see FirstChild( const char* value, bool throwIfNoChildren = true )
525                */
526                Node* FirstChild( const std::string& value, bool throwIfNoChildren = true ) const;
527
528                /**
529                The last child of this node.
530
531                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
532                @return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
533                @throws Exception When throwIfNoChildren is true, and TiXmlNode::LastChild returns Null.
534
535                @see TiXmlNode::LastChild
536                */
537                Node* LastChild( bool throwIfNoChildren = true ) const;
538
539                /**
540                @internal
541                The last child of this node with the matching @a value.
542
543                @overload
544                @param value                            Value to match.
545                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
546
547                @see LastChild( bool throwIfNoChildren = true )
548                */
549                Node* LastChild( const char* value, bool throwIfNoChildren = true ) const;
550
551                /**
552                The last child of this node with the matching @a value.
553
554                @overload
555                @param value                            Value to match.
556                @param throwIfNoChildren        [DEF] If true, will throw an exception if there are no children.
557
558                @see LastChild( const char* value, bool throwIfNoChildren = true )
559                */
560                Node* LastChild( const std::string& value, bool throwIfNoChildren = true ) const;
561
562                /**
563                An alternate way to walk the children of a node.
564                Simple wrapper for TiXmlNode::IterateChildren.
565
566                @param previous The previous Node* that was returned from IterateChildren.
567                @return NULL When there are no more children.
568                */
569                Node* IterateChildren( Node* previous ) const;
570
571                /**
572                This flavor of IterateChildren searches for children with a particular @a value.
573                Simple wrapper for TiXmlNode::IterateChildren.
574
575                @param value    The value you want to search for.
576                @param previous The previous Node* that was returned from IterateChildren.
577                @return NULL When there are no more children.
578                */
579                Node* IterateChildren( const std::string& value, Node* previous ) const;
580
581                /**
582                Adds a child past the LastChild.
583                Throws if you try to insert a document.
584
585                @note This takes a copy of @a addThis so it is not as efficiant as LinkEndChild.
586                @param addThis Node to insert.
587                @throws Exception When TiXmlNode::InsertEndChild returns Null
588
589                @see LinkEndChild
590                @see TiXmlNode::InsertEndChild
591                */
592                Node* InsertEndChild( Node& addThis );
593
594                /**
595                Adds a child past the LastChild.
596                Throws if you try to link a document.
597
598                @param childNode Node to link.
599                @throws Exception When TiXmlNode::LinkEndChild returns Null.
600
601                @see InsertEndChild
602                @see TiXmlNode::LinkEndChild
603                */
604                Node* LinkEndChild( Node* childNode );
605
606                /**
607                Adds a child before the specified child.
608                Throws if you try to insert a document.
609
610                @param beforeThis       Node that will have @a addThis linked before.
611                @param addThis          Node to insert before.
612                @throws Exception When TiXmlNode::InsertBeforeChild returns Null.
613
614                @see InsertAfterChild
615                @see TiXmlNode::InsertBeforeChild
616                */
617                Node* InsertBeforeChild( Node* beforeThis, Node& addThis );
618
619                /**
620                Adds a child after the specified child.
621                Throws if you try to insert a document.
622
623                @param afterThis        Node that will have @a addThis linked after.
624                @param addThis          Node to insert after.
625                @throws Exception When TiXmlNode::InsertAfterChild returns Null.
626
627                @see InsertBeforeChild
628                @see TiXmlNode::InsertAfterChild
629                */
630                Node* InsertAfterChild( Node* afterThis, Node& addThis );
631
632                /**
633                Replace a child of this node.
634                Throws if you try to replace with a document.
635
636                @param replaceThis      Node to replace.
637                @param withThis         Node that is replacing @a replaceThis.
638                @throws Exception When TiXmlNode::ReplaceChild returns Null.
639
640                @see TiXmlNode::ReplaceChild
641                */
642                Node* ReplaceChild( Node* replaceThis, Node& withThis );
643
644                /**
645                Delete a child of this node.
646
647                @param removeThis Node to delete.
648                @throws Exception When removeThis is not a child of this Node.
649
650                @see TiXmlNode::RemoveChild
651                */
652                void RemoveChild( Node* removeThis );
653
654                /**
655                Navigate to a sibling node.
656                Wrapper around TiXmlNode::PreviousSibling.
657
658                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
659                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
660                @throws Exception When TiXmlNode::PreviousSibling returns Null and 'throwIfNoSiblings' is true.
661                */
662                Node* PreviousSibling( bool throwIfNoSiblings = true ) const;
663
664                /**
665                Navigate to a sibling node with the given @a value.
666
667                @overload
668                @param value The value of the node to look for.
669                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
670
671                @see PreviousSibling( bool throwIfNoSiblings )
672                */
673                Node* PreviousSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
674
675                /**
676                @internal
677                Navigate to a sibling node with the given @a value.
678
679                @overload
680                @param value The value of the node to look for.
681                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
682
683                @see PreviousSibling( const std::string& value, bool throwIfNoSiblings )
684                */
685                Node* PreviousSibling( const char* value, bool throwIfNoSiblings = true ) const;
686
687                /**
688                Navigate to a sibling node.
689                Wrapper around TiXmlNode::NextSibling.
690
691                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
692                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
693                @throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
694                */
695                Node* NextSibling( bool throwIfNoSiblings = true ) const;
696
697                /**
698                Navigate to a sibling node with the given @a value.
699
700                @overload
701                @param value The value of the node to look for.
702                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
703
704                @see NextSibling( bool throwIfNoSiblings )
705                */
706                Node* NextSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
707
708                /**
709                @internal
710                Navigate to a sibling node with the given @a value.
711
712                @overload
713                @param value The value of the node to look for.
714                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
715
716                @see NextSibling( const std::string& value, bool throwIfNoSiblings )
717                */
718                Node* NextSibling( const char* value, bool throwIfNoSiblings = true ) const;
719
720                /**
721                @internal
722                Just for Iterator<>
723
724                @param value The value of nodes to iterate through
725                @param next [OUT] The pointer to the first valid node
726                */
727                template < class T >
728                        void IterateFirst( const std::string& value, T** first ) const
729                {
730                        *first = 0;
731                        for( Node* child = FirstChild( value, false ); child; child = child->NextSibling( value, false ) )
732                        {
733                                *first = dynamic_cast< T* >( child );
734                                if ( 0 != *first )
735                                {
736                                        return;
737                                }
738                        }
739                }
740
741                virtual void IterateFirst( const std::string&, Attribute** ) const
742                {
743                        TICPPTHROW( "Attributes can only be iterated with Elements." )
744                }
745
746                /**
747                @internal
748                Just for Iterator<>
749
750                @param value The value of nodes to iterate through
751                @param next [OUT] The pointer to the next valid node
752                */
753                template < class T >
754                        void IterateNext( const std::string& value, T** next ) const
755                {
756                        Node* sibling = NextSibling( value, false );
757                        *next = dynamic_cast< T* >( sibling );
758
759                        while ( ( 0 != sibling ) && ( 0 == *next ) )
760                        {
761                                sibling = sibling->NextSibling( value, false );
762                                *next = dynamic_cast< T* >( sibling );
763                        }
764                }
765
766                /**
767                @internal
768                Just for Iterator<>
769
770                @param value The value of nodes to iterate through
771                @param previous [OUT] The pointer to the previous valid node
772                */
773                template < class T >
774                        void IteratePrevious( const std::string& value, T** previous  ) const
775                {
776                        Node* sibling = PreviousSibling( value, false );
777                        *previous = dynamic_cast< T* >( sibling );
778
779                        while ( ( 0 != sibling ) && ( 0 == *previous ) )
780                        {
781                                sibling = sibling->PreviousSibling( value, false );
782                                *previous = dynamic_cast< T* >( sibling );
783                        }
784                }
785
786                /**
787                Navigate to a sibling element.
788                Wrapper around TiXmlNode::NextSibling.
789
790                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling element.
791                @return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
792                @throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
793                */
794                Element* NextSiblingElement( bool throwIfNoSiblings = true ) const;
795
796                /**
797                Navigate to a sibling element with the given @a value.
798
799                @overload
800                @param value The value of the element to look for.
801                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
802                @see NextSiblingElement( bool throwIfNoSiblings )
803                */
804                Element* NextSiblingElement( const std::string& value, bool throwIfNoSiblings = true ) const;
805
806                /**
807                @internal
808                Navigate to a sibling element with the given @a value.
809
810                @overload
811                @param value The value of the element to look for.
812                @param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
813
814                @see NextSiblingElement( const std::string& value, bool throwIfNoSiblings )
815                */
816                Element* NextSiblingElement( const char* value, bool throwIfNoSiblings = true ) const;
817
818                /**
819                The first child element of this node.
820
821                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
822                @return Pointer to child, Null if no element children and 'throwIfNoChildren' is false.
823                @throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChildElement returns Null.
824
825                @see TiXmlNode::FirstChildElement
826                */
827                Element* FirstChildElement( bool throwIfNoChildren = true ) const;
828
829                /**
830                @internal
831                The first child element of this node with the matching @a value.
832
833                @overload
834                @param value Value to match.
835                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
836
837                @see FirstChildElement( bool throwIfNoChildren = true )
838                */
839                Element* FirstChildElement( const char* value, bool throwIfNoChildren = true ) const;
840
841                /**
842                The first child element of this node with the matching @a value.
843
844                @overload
845                @param value Value to match.
846                @param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
847
848                @see FirstChildElement( const char* value, bool throwIfNoChildren = true )
849                */
850                Element* FirstChildElement( const std::string& value, bool throwIfNoChildren = true ) const;
851
852                /**
853                Query the type (as TiXmlNode::NodeType ) of this node.
854                */
855                int Type() const;
856
857                /**
858                Return a pointer to the Document this node lives in.
859
860                @param throwIfNoDocument [DEF] If true, will throw an exception if this node is not linked under a Document.
861                @return A pointer to the Document this node lives in, NULL if not linked under a Document, and 'throwIfNoDocument' is false.
862                @throws Exception When this node is not linked under a Document and 'throwIfNoDocument' is true.
863                */
864                Document* GetDocument( bool throwIfNoDocument = true ) const;
865
866                /**
867                Check if this node has no children.
868
869                @return true if this node has no children.
870                */
871                bool NoChildren() const;
872
873                /**
874                Pointer conversion ( NOT OBJECT CONVERSION ) - replaces TiXmlNode::ToElement, TiXmlNode::ToDocument, TiXmlNode::ToComment, etc.
875
876                @throws Exception When the target is not an object of class T
877                @warning Some ancient compilers do not support explicit specification of member template arguments, which this depends on ( e.g. VC6 ).
878                */
879                template < class T >
880                        T* To() const
881                {
882                        T* pointer = dynamic_cast< T* >( this );
883                        if ( 0 == pointer )
884                        {
885                                std::string thisType = typeid( this ).name();
886                                std::string targetType = typeid( T ).name();
887                                std::string thatType = typeid( *this ).name();
888                                TICPPTHROW( "The " << thisType.substr( 6 ) << " could not be casted to a " << targetType.substr( 6 )
889                                        << " *, because the target object is not a " << targetType.substr( 6 ) << ". (It is a " << thatType.substr( 6 ) << ")" );
890                        }
891                        return pointer;
892                }
893
894                /**
895                Pointer conversion - replaces TiXmlNode::ToDocument.
896
897                @throws Exception When this node is not a Document.
898                */
899                Document* ToDocument() const;
900
901                /**
902                Pointer conversion - replaces TiXmlNode::ToElement.
903
904                @throws Exception When this node is not a Element.
905                */
906                Element* ToElement() const;
907
908                /**
909                Pointer conversion - replaces TiXmlNode::ToComment.
910
911                @throws Exception When this node is not a Comment.
912                */
913                Comment* ToComment() const;
914
915                /**
916                Pointer conversion - replaces TiXmlNode::ToText.
917
918                @throws Exception When this node is not a Text.
919                */
920                Text* ToText() const;
921
922                /**
923                Pointer conversion - replaces TiXmlNode::ToDeclaration.
924
925                @throws Exception When this node is not a Declaration.
926                */
927                Declaration* ToDeclaration() const;
928
929                /**
930                Pointer conversion - replaces TiXmlNode::ToStylesheetReference.
931
932                @throws Exception When this node is not a StylesheetReference.
933                */
934                StylesheetReference* ToStylesheetReference() const;
935
936                /**
937                Create an exact duplicate of this node and return it.
938
939                @note Using auto_ptr to manage the memory declared on the heap by TiXmlNode::Clone.
940                @code
941                // Now using clone
942                ticpp::Document doc( "C:\\Test.xml" );
943                ticpp::Node* sectionToClone;
944                sectionToClone = doc.FirstChild( "settings" );
945                std::auto_ptr< ticpp::Node > clonedNode = sectionToClone->Clone();
946                // Now you can use the clone.
947                ticpp::Node* node2 = clonedNode->FirstChildElement()->FirstChild();
948                ...
949                // After the variable clonedNode goes out of scope it will automatically be cleaned up.
950                @endcode
951                @return Pointer the duplicate node.
952                */
953                std::auto_ptr< Node > Clone() const;
954
955                /**
956                Accept a hierchical visit the nodes in the TinyXML DOM.
957                @return The boolean returned by the visitor.
958                */
959                bool Accept( TiXmlVisitor* visitor ) const;
960
961                /**
962                Stream input operator.
963                */
964                friend std::istream& operator >>( std::istream& in, Node& base )
965                {
966                        in >> *base.GetTiXmlPointer();
967                        return in;
968                }
969
970                /**
971                Stream output operator.
972                */
973                friend std::ostream& operator <<( std::ostream& out, Node& base )
974                {
975                        out << *base.GetTiXmlPointer();
976                        return out;
977                }
978
979        protected:
980                /**
981                @internal
982                Allows NodeImp to use Node*'s.
983                */
984                virtual TiXmlNode* GetTiXmlPointer() const = 0;
985
986                TiXmlBase* GetBasePointer() const
987                {
988                        return GetTiXmlPointer();
989                }
990
991                /**
992                @internal
993                Constructs the correct child of Node, based on the Type of the TiXmlNode*.
994                */
995                Node* NodeFactory( TiXmlNode* tiXmlNode, bool throwIfNull = true, bool rememberSpawnedWrapper = true ) const;
996
997        };
998
999        /** Iterator for conveniently stepping through Nodes and Attributes.
1000        TinyXML++ introduces iterators:
1001        @code
1002        ticpp::Iterator< ticpp::Node > child;
1003        for ( child = child.begin( parent ); child != child.end(); child++ )
1004        @endcode
1005
1006        Iterators have the added advantage of filtering by type:
1007        @code
1008        // Only iterates through Comment nodes
1009        ticpp::Iterator< ticpp::Comment > child;
1010        for ( child = child.begin( parent ); child != child.end(); child++ )
1011        @endcode
1012
1013        @code
1014        // Only iterates through Element nodes with value "ElementValue"
1015        ticpp::Iterator< ticpp::Element > child( "ElementValue" );
1016        for ( child = child.begin( parent ); child != child.end(); child++ )
1017        @endcode
1018
1019        Finally, Iterators also work with Attributes
1020        @code
1021        ticpp::Iterator< ticpp::Attribute > attribute;
1022        for ( attribute = attribute.begin( element ); attribute != attribute.end(); attribute++ )
1023        @endcode
1024        */
1025        template < class T = Node >
1026                class Iterator
1027        {
1028        private:
1029                T* m_p;                                 /**< Internal Pointer */
1030                std::string m_value;    /**< Value for NextSibling  calls */
1031
1032        public:
1033
1034                /**
1035                For for loop comparisons.
1036                @param parent The parent of the nodes to iterate.
1037                @return The first child of type T.
1038                @code
1039                ticpp::Iterator< ticpp::Node > child;
1040                for ( child = child.begin( parent ); child != child.end(); child++ )
1041                @endcode
1042                */
1043                T* begin( const Node* parent ) const
1044                {
1045                        T* pointer;
1046                        parent->IterateFirst( m_value, &pointer );
1047                        return pointer;
1048                }
1049
1050                /**
1051                For for loop comparisons.
1052                @return NULL
1053                @code
1054                ticpp::Iterator< ticpp::Node > child;
1055                for ( child = child.begin( parent ); child != child.end(); child++ )
1056                @endcode
1057                */
1058                T* end() const
1059                {
1060                        return 0;
1061                }
1062
1063                /** Constructor.
1064                @param value If not empty, this iterator will only visit nodes with matching value.
1065                @code
1066                // Only iterates through Element nodes with value "ElementValue"
1067                ticpp::Iterator< ticpp::Element > child( "ElementValue" );
1068                for ( child = child.begin( parent ); child != child.end(); child++ )
1069                @endcode
1070                */
1071                Iterator( const std::string& value = "" )
1072                        : m_p( 0 ), m_value( value )
1073                {
1074                }
1075
1076                /// Constructor
1077                Iterator( T* node, const std::string& value = "" )
1078                        : m_p( node ), m_value( value )
1079                {
1080                }
1081
1082                /// Constructor
1083                Iterator( const Iterator& it, const std::string& value  = "" )
1084                        : m_p( it.m_p ), m_value( value )
1085                {
1086                }
1087
1088                /**
1089                Gets internal pointer.
1090                @return The internal pointer.
1091                */
1092                T* Get() const
1093                {
1094                        return m_p;
1095                }
1096
1097                /** Sets internal pointer */
1098                Iterator& operator=( const Iterator& it )
1099                {
1100                        m_p = it.m_p;
1101                        return *this;
1102                }
1103
1104                /** Sets internal pointer */
1105                Iterator& operator=( T* p )
1106                {
1107                        m_p = p;
1108                        return *this;
1109                }
1110
1111                /** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
1112                Iterator& operator++()
1113                {
1114                        m_p->IterateNext( m_value, &m_p );
1115                        return *this;
1116                }
1117
1118                /** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
1119                Iterator& operator++(int)
1120                {
1121                        return this->operator ++();
1122                }
1123
1124                /** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
1125                Iterator& operator--()
1126                {
1127                        m_p->IteratePrevious( m_value, &m_p );
1128                        return *this;
1129                }
1130
1131                /** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
1132                Iterator& operator--(int)
1133                {
1134                        return this->operator --();
1135                }
1136
1137                /** Compares internal pointer */
1138                bool operator!=( T* p ) const
1139                {
1140                        return m_p != p;
1141                }
1142
1143                /** Compares internal pointer */
1144                bool operator!=( const Iterator& it ) const
1145                {
1146                        return m_p != it.m_p;
1147                }
1148
1149                /** Compares internal pointer* */
1150                bool operator==( T* p ) const
1151                {
1152                        return m_p == p;
1153                }
1154
1155                /** Compares internal pointer */
1156                bool operator==( const Iterator& it ) const
1157                {
1158                        return m_p == it.m_p;
1159                }
1160
1161                /** So Iterator behaves like a STL iterator */
1162                T* operator->() const
1163                {
1164                        return m_p;
1165                }
1166
1167                /** So Iterator behaves like a STL iterator */
1168                T& operator*() const
1169                {
1170                        return *m_p;
1171                }
1172        };
1173
1174        /** Implementation of Node wrapper */
1175        template < class T >
1176                class NodeImp : public Node
1177        {
1178        protected:
1179
1180                T* m_tiXmlPointer;              /**< Internal pointer to the TiXml Class which is being wrapped */
1181
1182                /**
1183                @internal
1184                Gets the internal TinyXML pointer.
1185
1186                @returns The internal TiXmlNode*.
1187                */
1188                TiXmlNode* GetTiXmlPointer() const
1189                {
1190                        ValidatePointer();
1191                        return m_tiXmlPointer;
1192                }
1193
1194                /**
1195                @internal
1196                Sets the internal pointer.
1197                Saves a copy of the pointer to the RC object.
1198
1199                @param newPointer TiXmlNode* to set.
1200                */
1201                void SetTiXmlPointer( T* newPointer )
1202                {
1203                        m_tiXmlPointer = newPointer;
1204                        SetImpRC( newPointer );
1205                }
1206
1207                /**
1208                @internal
1209                Constructor used by child classes.
1210                */
1211                NodeImp( T* tiXmlPointer )
1212                {
1213                        // Check for NULL pointers
1214                        if ( 0 == tiXmlPointer )
1215                        {
1216                                TICPPTHROW( "Can not create a " << typeid( T ).name() );
1217                        }
1218                        SetTiXmlPointer( tiXmlPointer );
1219                        m_impRC->IncRef();
1220                }
1221
1222                /**
1223                @internal
1224                Updates the reference count for the old and new pointers.
1225                In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in.
1226                */
1227                virtual void operator=( const NodeImp<T>& copy )
1228                {
1229                        DeleteSpawnedWrappers();
1230
1231                        // Dropping the reference to the old object
1232                        this->m_impRC->DecRef();
1233
1234                        // Pointing to the new Object
1235                        SetTiXmlPointer( copy.m_tiXmlPointer );
1236
1237                        // The internal tixml pointer changed in the above line
1238                        this->m_impRC->IncRef();
1239                }
1240
1241                /**
1242                @internal
1243                Updates the reference count for the old and new pointers.
1244                In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in
1245                */
1246                NodeImp( const NodeImp<T>& copy ) : Node( copy )
1247                {
1248                        // Pointing to the new Object
1249                        SetTiXmlPointer( copy.m_tiXmlPointer );
1250
1251                        // The internal tixml pointer changed in the above line
1252                        this->m_impRC->IncRef();
1253                }
1254
1255        public:
1256
1257                /*
1258                Deletes the spawned wrapper objects.
1259                Decrements reference count.
1260                */
1261                virtual ~NodeImp()
1262                {
1263                        // The spawnedWrappers need to be deleted before m_tiXmlPointer
1264                        DeleteSpawnedWrappers();
1265                        m_impRC->DecRef();
1266                }
1267        };
1268
1269        /** Wrapper around TiXmlComment */
1270        class Comment : public NodeImp< TiXmlComment >
1271        {
1272        public:
1273
1274                /**
1275                Constructor.
1276                */
1277                Comment();
1278
1279                /**
1280                Constructor.
1281                */
1282                Comment( TiXmlComment* comment );
1283
1284                /**
1285                Constructor.
1286                */
1287                Comment( const std::string& comment );
1288        };
1289
1290        /** Wrapper around TiXmlText */
1291        class Text : public NodeImp< TiXmlText >
1292        {
1293        public:
1294
1295                /**
1296                Constructor.
1297                */
1298                Text();
1299
1300                /**
1301                Constructor.
1302                @overload
1303                */
1304                Text( TiXmlText* text );
1305
1306                /**
1307                Constructor.
1308                @overload
1309                */
1310                Text( const std::string& value );
1311
1312                /**
1313                Streams value into a string and creates a Text with it.
1314                Uses ToString to covert the parameter to a string.
1315
1316                @param value The value of the Text node.
1317                @throws Exception
1318
1319                @see TiXmlText
1320        */
1321                template < class T >
1322                        Text( const T& value )
1323                                : NodeImp< TiXmlText >( new TiXmlText( ToString( value ) ) )
1324                {
1325                        m_impRC->InitRef();
1326                }
1327        };
1328
1329        /** Wrapper around TiXmlDocument */
1330        class Document : public NodeImp< TiXmlDocument >
1331        {
1332        public:
1333                /**
1334                Default Constructor.
1335                Create an empty document, that has no name.
1336                */
1337                Document();
1338
1339                /**
1340                Constructor.
1341                */
1342                Document( TiXmlDocument* document );
1343
1344                /**
1345                Constructor.
1346                */
1347                Document( const char* documentName );
1348
1349                /**
1350                Constructor.
1351                Create a document with a name. The name of the document is also the filename of the xml.
1352
1353                @param documentName Name to set in the Document.
1354                */
1355                Document( const std::string& documentName );
1356
1357                /**
1358                Load a file using the current document value. Throws if load is unsuccessful.
1359
1360                @param encoding Sets the documents encoding.
1361                @see TiXmlEncoding
1362                @throws Exception
1363                */
1364                void LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1365
1366                /**
1367                Save a file using the current document value. Throws if it can't save the file.
1368
1369                @throws Exception
1370                */
1371                void SaveFile() const;
1372
1373                /**
1374                Load a file using the given filename. Throws if load is unsuccessful.
1375
1376                @param filename File to load.
1377                @param encoding Sets the documents encoding.
1378                @see TiXmlEncoding
1379                @throws Exception
1380                */
1381                void LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1382
1383                /**
1384                @copydoc Document::LoadFile( const std::string&, TiXmlEncoding )
1385                */
1386                void LoadFile( const char* filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1387
1388                /**
1389                Save a file using the given filename. Throws if it can't save the file.
1390
1391                @param filename File to save.
1392                @throws Exception
1393                */
1394                void SaveFile( const std::string& filename ) const;
1395
1396                /**
1397                Parse the given xml data.
1398
1399                @param xml Xml to parse.
1400                @param throwIfParseError [DEF] If true, throws when there is a parse error.
1401                @param encoding Sets the documents encoding.
1402                @throws Exception
1403                */
1404                void Parse( const std::string& xml, bool throwIfParseError = true, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1405        };
1406
1407        /** Wrapper around TiXmlElement */
1408        class Element : public NodeImp< TiXmlElement >
1409        {
1410        public:
1411                /**
1412                Default Constructor.
1413                */
1414                Element();
1415
1416                /**
1417                Default Constructor. Initializes all the variables.
1418                @param value The value of the element.
1419                */
1420                Element( const std::string& value );
1421
1422                /**
1423                Default Constructor. Initializes all the variables.
1424                @param value The value of the element.
1425                */
1426                Element( const char* value );
1427
1428                /**
1429                Constructor.
1430                */
1431                Element( TiXmlElement* element );
1432
1433                /**
1434                Constructor that allows you to set the element text
1435                @param value The value of the element.
1436                @param text The text to set.
1437                */
1438                template < class T >
1439                        Element( const std::string& value, const T& text )
1440                        : NodeImp< TiXmlElement >( new TiXmlElement( value ) )
1441                {
1442                        m_impRC->InitRef();
1443                        SetText( text );
1444                }
1445
1446                /**
1447                Access the first attribute in this element.
1448
1449                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1450                @return The first attribute, NULL if there are none and @a throwIfNoAttributes is true
1451                */
1452                Attribute* FirstAttribute( bool throwIfNoAttributes = true ) const;
1453
1454                /**
1455                Access the last attribute in this element.
1456
1457                @param throwIfNoAttributes [DEF] If true, throws when there are no attributes
1458                @return The last attribute, NULL if there are none and @a throwIfNoAttributes is true
1459                */
1460                Attribute* LastAttribute( bool throwIfNoAttributes = true ) const;
1461
1462                /**
1463                @internal
1464                Just for Iterator<>
1465
1466                @param value The value of nodes to iterate through
1467                @param next [OUT] The pointer to the first valid node
1468                */
1469                void IterateFirst( const std::string&, Attribute** first ) const
1470                {
1471                        *first = 0;
1472                        for( Attribute* child = FirstAttribute( false ); child; child = child->Next( false ) )
1473                        {
1474                                *first = dynamic_cast< Attribute* >( child );
1475                                if ( 0 != *first )
1476                                {
1477                                        return;
1478                                }
1479                        }
1480                }
1481
1482                /**
1483                Sets an attribute of name to a given value.
1484                The attribute will be created if it does not exist, or changed if it does.
1485                Uses ToString to convert the @a value to a string, so there is no need to use any other SetAttribute methods.
1486
1487                @see GetAttribute
1488                */
1489                template < class T >
1490                        void SetAttribute ( const std::string& name, const T& value )
1491                {
1492                        ValidatePointer();
1493                        m_tiXmlPointer->SetAttribute( name, ToString( value ) );
1494                }
1495
1496                /**
1497                Gets the text of an Element.
1498
1499                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1500                @note This only works if the Text is the FirstChild node
1501                @throws Exception When there is no text and throwIfNotFound is true
1502
1503                @see GetText( T* value, bool throwIfNotFound = false )
1504                @see GetTextOrDefault
1505                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1506                @see TiXmlElement::GetText
1507                */
1508                std::string GetText( bool throwIfNotFound = true ) const
1509                {
1510                        // Get the element's text value as a std::string
1511                        std::string temp;
1512                        if ( !GetTextImp( &temp ) )
1513                        {
1514                                if ( throwIfNotFound )
1515                                {
1516                                        TICPPTHROW( "Text does not exists in the current element" );
1517                                }
1518                        }
1519
1520                        return temp;
1521                }
1522
1523                /**
1524                Gets the text of an Element, if it doesn't exist it will return the defaultValue.
1525
1526                @param defaultValue                     What to put in 'value' if there is no text in this element
1527                @note This only works if the Text is the FirstChild node
1528
1529                @see GetText
1530                @see GetText( T* value, bool throwIfNotFound = false )
1531                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1532                @see TiXmlElement::GetText
1533                */
1534                std::string GetTextOrDefault( const std::string& defaultValue ) const
1535                {
1536                        // Get the element's text value as a std::string
1537                        std::string temp;
1538                        if ( !GetTextImp( &temp ) )
1539                        {
1540                                return defaultValue;
1541                        }
1542
1543                        return temp;
1544                }
1545
1546                /**
1547                Gets the text value of an Element, if it doesn't exist it will return the defaultValue.
1548                Uses FromString to convert the string to the type of choice
1549
1550                @param value            [OUT]   The container for the returned value
1551                @param defaultValue                     What to put in 'value' if there is no text in this element
1552                @note This is different than GetText() in that it will covert the text to what ever type you want.
1553                @note This only works if the Text is the FirstChild node
1554
1555                @see GetText
1556                @see GetText( T* value, bool throwIfNotFound = false )
1557                @see GetTextOrDefault( const std::string& defaultValue )
1558                @see TiXmlElement::GetText
1559                */
1560                template < class T, class DefaultT >
1561                        void GetTextOrDefault( T* value, const DefaultT& defaultValue ) const
1562                {
1563                        // Get the element's text value as a std::string
1564                        std::string temp;
1565                        if ( !GetTextImp( &temp ) )
1566                        {
1567                                // The text value does not exist - set value to the default
1568                                *value = defaultValue;
1569                                return;
1570                        }
1571
1572                        // Stream the value from the string to T
1573                        FromString( temp, value );
1574                }
1575
1576                /**
1577                Gets the text of an Element.
1578                Uses FromString to convert the string to the type of choice.
1579
1580                @param value                    [OUT]   The container for the returned value
1581                @param throwIfNotFound  [DEF]   If true, will throw an exception if there is no text in this element
1582                @note This is different than GetText() in that it will covert the text to what ever type you want
1583                @note This only works if the Text is the FirstChild node
1584                @throws Exception When there is no text and throwIfNotFound is true
1585
1586                @see GetText
1587                @see GetTextOrDefault
1588                @see GetTextOrDefault( T* value, const DefaultT& defaultValue )
1589                @see TiXmlElement::GetText
1590                */
1591                template< class T >
1592                        void GetText( T* value, bool throwIfNotFound = true ) const
1593                {
1594                        // Get the element's text value as a std::string
1595                        std::string temp;
1596                        if ( !GetTextImp( &temp ) )
1597                        {
1598                                if ( throwIfNotFound )
1599                                {
1600                                        TICPPTHROW( "Text does not exists in the current element" );
1601                                }
1602                                else
1603                                {
1604                                        return;
1605                                }
1606                        }
1607
1608                        // Stream the value from the string to T
1609                        FromString( temp, value );
1610                }
1611
1612                /**
1613                Convenience function to set the text of an element.
1614                Creates a Text node and inserts it as the first child.
1615                Uses ToString to convert the parameter to a string.
1616
1617                @param value The text to set.
1618                */
1619                template < class T >
1620                        void SetText( const T& value )
1621                {
1622                        ValidatePointer();
1623                        std::string temp = ToString( value );
1624
1625                        if ( m_tiXmlPointer->NoChildren() )
1626                        {
1627                                m_tiXmlPointer->LinkEndChild( new TiXmlText( temp ) );
1628                        }
1629                        else
1630                        {
1631                                if ( 0 == m_tiXmlPointer->GetText() )
1632                                {
1633                                        m_tiXmlPointer->InsertBeforeChild( m_tiXmlPointer->FirstChild(), TiXmlText( temp ) );
1634                                }
1635                                else
1636                                {
1637                                        // There already is text, so change it
1638                                        m_tiXmlPointer->FirstChild()->SetValue( temp );
1639                                }
1640                        }
1641                }
1642
1643                /**
1644                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1645                Uses FromString to convert the string to the type of choice.
1646
1647                @param name                     The name of the attribute you are querying.
1648                @param value            [OUT] The container for the returned value.
1649                @param defaultValue     What to put in @a value if there is no attribute in this element.
1650                @throws Exception
1651
1652                @see GetAttribute
1653                */
1654                template < class T, class DefaulT >
1655                        void GetAttributeOrDefault( const std::string& name, T* value, const DefaulT& defaultValue ) const
1656                {
1657                        // Get the attribute's value as a std::string
1658                        std::string temp;
1659                        if ( !GetAttributeImp( name, &temp ) )
1660                        {
1661                                // The attribute does not exist - set value to the default
1662                                *value = defaultValue;
1663                                return;
1664                        }
1665
1666                        // Stream the value from the string to T
1667                        FromString( temp, value );
1668                }
1669
1670                /**
1671                Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
1672
1673                @param name                     The name of the attribute you are querying.
1674                @param defaultValue     What to put in @a value if there is no attribute in this element.
1675
1676                @see GetAttribute
1677                */
1678                std::string GetAttributeOrDefault( const std::string& name, const std::string& defaultValue ) const;
1679
1680                /**
1681                Gets an attribute of @a name from an element.
1682                Uses FromString to convert the string to the type of choice.
1683
1684                @param name                             The name of the attribute you are querying.
1685                @param value                    [OUT]   The container for the returned value
1686                @param throwIfNotFound  [DEF]   If true, will throw an exception if the attribute doesn't exist
1687                @throws Exception When the attribute doesn't exist and throwIfNotFound is true
1688
1689                @see GetAttributeOrDefault
1690                */
1691                template< class T >
1692                        void GetAttribute( const std::string& name, T* value, bool throwIfNotFound = true ) const
1693                {
1694                        // Get the attribute's value as a std::string
1695                        std::string temp;
1696                        if ( !GetAttributeImp( name, &temp ) )
1697                        {
1698                                if ( throwIfNotFound )
1699                                {
1700                                        TICPPTHROW( "Attribute does not exist" );
1701                                }
1702                                else
1703                                {
1704                                        return;
1705                                }
1706                        }
1707
1708                        // Stream the value from the string to T
1709                        FromString( temp, value );
1710                }
1711
1712                /**
1713                Gets an attribute of @a name from an element.
1714                Returns an empty string if the attribute does not exist.
1715
1716                @param name     The name of the attribute you are querying.
1717                @return The value of the attribute, or an empty string if it does not exist.
1718
1719                @see GetAttributeOrDefault
1720                */
1721                std::string GetAttribute( const std::string& name ) const;
1722
1723        private:
1724
1725                /**
1726                @internal
1727                Implimentation of the GetAttribute and GetAttributeOrDefault template methods.
1728                */
1729                bool GetAttributeImp( const std::string& name, std::string* value ) const;
1730
1731                /**
1732                @internal
1733                Implimentation of the GetText, GetTextOrDefault, GetTextValue, and GetTextValueOrDefault template methods.
1734                */
1735                bool GetTextImp( std::string* value ) const;
1736        };
1737
1738        /** Wrapper around TiXmlDeclaration */
1739        class Declaration : public NodeImp< TiXmlDeclaration >
1740        {
1741        public:
1742                /**
1743                Default Constructor. Construct an empty declaration.
1744                */
1745                Declaration();
1746
1747                /**
1748                Constructor.
1749                */
1750                Declaration( TiXmlDeclaration* declaration );
1751
1752                /**
1753                Constructor.
1754                */
1755                Declaration( const std::string& version, const std::string& encoding, const std::string& standalone );
1756
1757                /**
1758                Version. Will return an empty string if none was found.
1759                */
1760                std::string Version() const;
1761
1762                /**
1763                Encoding. Will return an empty string if none was found.
1764                */
1765                std::string Encoding() const;
1766
1767                /**
1768                StandAlone. Is this a standalone document?
1769                */
1770                std::string Standalone() const;
1771        };
1772
1773        /** Wrapper around TiXmlStylesheetReference */
1774        class StylesheetReference : public NodeImp< TiXmlStylesheetReference >
1775        {
1776        public:
1777                /**
1778                Default Constructor. Construct an empty declaration.
1779                */
1780                StylesheetReference();
1781
1782                /**
1783                Constructor.
1784                */
1785                StylesheetReference( TiXmlStylesheetReference* stylesheetReference );
1786
1787                /**
1788                Constructor.
1789                */
1790                StylesheetReference( const std::string& type, const std::string& href );
1791
1792                /**
1793                Type. Will return an empty string if none was found.
1794                */
1795                std::string Type() const;
1796
1797                /**
1798                Href. Will return an empty string if none was found.
1799                */
1800                std::string Href() const;
1801        };
1802}
1803
1804#endif  // TICPP_INCLUDED
1805
1806#endif // TIXML_USE_TICPP
Note: See TracBrowser for help on using the repository browser.