Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/tinyxml/ticpp.h @ 1656

Last change on this file since 1656 was 1505, checked in by rgrieder, 16 years ago

f* svn: It doesn't even inform you if you attempt to set a non existing property. It is svn:eol-style and not eol-style when using the command by the way…

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