00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef TAG_H__
00015 #define TAG_H__
00016
00017 #include "gloox.h"
00018
00019 #include <string>
00020 #include <list>
00021 #include <utility>
00022
00023 namespace gloox
00024 {
00025
00026 class Tag;
00027
00031 typedef std::list<Tag*> TagList;
00032
00036 typedef std::list<const Tag*> ConstTagList;
00037
00046 class GLOOX_API Tag
00047 {
00048
00049 friend class Parser;
00050
00051 public:
00052
00059 class GLOOX_API Attribute
00060 {
00061
00062 friend class Tag;
00063
00064 public:
00077 Attribute( Tag* parent, const std::string& name, const std::string& value,
00078 const std::string& xmlns = EmptyString );
00079
00086 Attribute( const std::string& name, const std::string& value,
00087 const std::string& xmlns = EmptyString );
00088
00093 Attribute( const Attribute& attr );
00094
00098 virtual ~Attribute() {}
00099
00104 const std::string& name() const { return m_name; }
00105
00110 const std::string& value() const { return m_value; }
00111
00118 bool setValue( const std::string& value );
00119
00124 const std::string& xmlns() const;
00125
00132 bool setXmlns( const std::string& xmlns );
00133
00140 bool setPrefix( const std::string& prefix );
00141
00146 const std::string& prefix() const;
00147
00152 const std::string xml() const;
00153
00158 bool operator==( const Attribute &right ) const
00159 { return m_name == right.m_name && m_value == right.m_value && m_xmlns == right.m_xmlns; }
00160
00165 bool operator!=( const Attribute &right ) const
00166 { return !( *this == right ); }
00167
00171 operator bool() const { return !m_name.empty(); }
00172
00173 private:
00174 void init( const std::string& name, const std::string& value,
00175 const std::string& xmlns );
00176 Tag* m_parent;
00177 std::string m_name;
00178 std::string m_value;
00179 std::string m_xmlns;
00180 std::string m_prefix;
00181
00182 };
00183
00187 typedef std::list<Attribute*> AttributeList;
00188
00196 Tag( const std::string& name, const std::string& cdata = EmptyString );
00197
00205 Tag( Tag* parent, const std::string& name, const std::string& cdata = EmptyString );
00206
00213 Tag( const std::string& name, const std::string& attrib, const std::string& value );
00214
00223 Tag( Tag* parent, const std::string& name, const std::string& attrib, const std::string& value );
00224
00228 virtual ~Tag();
00229
00235 const std::string xml() const;
00236
00244 bool setPrefix( const std::string& prefix );
00245
00251 const std::string& prefix() const { return m_prefix; }
00252
00258 const std::string& prefix( const std::string& xmlns ) const;
00259
00269
00270
00280 bool setXmlns( const std::string& xmlns, const std::string& prefix = EmptyString );
00281
00288 const std::string& xmlns() const;
00289
00307 const std::string& xmlns( const std::string& prefix ) const;
00308
00319 bool addAttribute( Attribute* attr );
00320
00329 bool addAttribute( const std::string& name, const std::string& value );
00330
00340 bool addAttribute( const std::string& name, int value );
00341
00351 bool addAttribute( const std::string& name, long value );
00352
00361 void setAttributes( const AttributeList& attributes );
00362
00367 void addChild( Tag* child );
00368
00374 void addChildCopy( const Tag* child );
00375
00382 bool setCData( const std::string& cdata );
00383
00390 bool addCData( const std::string& cdata );
00391
00396 const std::string& name() const { return m_name; }
00397
00402 const std::string cdata() const;
00403
00408 const AttributeList& attributes() const;
00409
00414 const TagList& children() const;
00415
00421 const std::string& findAttribute( const std::string& name ) const;
00422
00429 bool hasAttribute( const std::string& name, const std::string& value = EmptyString ) const;
00430
00437 Tag* findChild( const std::string& name ) const;
00438
00447 Tag* findChild( const std::string& name, const std::string& attr,
00448 const std::string& value = EmptyString ) const;
00449
00458 bool hasChild( const std::string& name, const std::string& attr = EmptyString,
00459 const std::string& value = EmptyString ) const;
00460
00468 Tag* findChildWithAttrib( const std::string& attr, const std::string& value = EmptyString ) const;
00469
00477 inline bool hasChildWithAttrib( const std::string& attr,
00478 const std::string& value = EmptyString ) const
00479 { return findChildWithAttrib( attr, value ) ? true : false; }
00480
00489 TagList findChildren( const std::string& name, const std::string& xmlns = EmptyString ) const;
00490
00497 void removeChild( const std::string& name, const std::string& xmlns = EmptyString );
00498
00504 void removeChild( Tag* tag );
00505
00512 void removeAttribute( const std::string& attr, const std::string& value = EmptyString,
00513 const std::string& xmlns = EmptyString );
00514
00522 bool hasChildWithCData( const std::string& name, const std::string& cdata ) const;
00523
00528 Tag* parent() const { return m_parent; }
00529
00535 Tag* clone() const;
00536
00547 const std::string findCData( const std::string& expression ) const;
00548
00559 const Tag* findTag( const std::string& expression ) const;
00560
00570 ConstTagList findTagList( const std::string& expression ) const;
00571
00577 bool operator==( const Tag &right ) const;
00578
00584 bool operator!=( const Tag &right ) const { return !( *this == right ); }
00585
00589 operator bool() const { return !m_name.empty(); }
00590
00591 private:
00597 Tag( Tag* tag );
00598
00602 enum XPathError
00603 {
00604 XPNoError,
00605 XPExpectedLeftOperand,
00606 XPUnexpectedToken
00607 };
00608
00609 enum NodeType
00610 {
00611 TypeTag,
00612 TypeString
00613 };
00614
00615 struct Node
00616 {
00617 Node( NodeType _type, Tag* _tag ) : type( _type ), tag( _tag ) {}
00618 Node( NodeType _type, std::string* _str ) : type( _type ), str( _str ) {}
00619 ~Node() {}
00620
00621 NodeType type;
00622 union
00623 {
00624 Tag* tag;
00625 std::string* str;
00626 };
00627 };
00628
00629 typedef std::list<Node*> NodeList;
00630 typedef std::list<std::string*> StringPList;
00631
00632 Tag* m_parent;
00633 TagList* m_children;
00634 StringPList* m_cdata;
00635 AttributeList* m_attribs;
00636 NodeList* m_nodes;
00637 std::string m_name;
00638 std::string m_xmlns;
00639 StringMap* m_xmlnss;
00640 std::string m_prefix;
00641
00642 enum TokenType
00643 {
00644 XTNone,
00645 XTLeftParenthesis,
00646 XTRightParenthesis,
00647 XTNodeSet,
00648 XTInteger,
00649 XTElement,
00650 XTLeftBracket,
00651 XTRightBracket,
00652 XTFunction,
00653 XTAsterisk,
00654 XTAttribute,
00655 XTLiteralInside,
00656 XTLiteral,
00657 XTDot,
00658 XTDoubleDot,
00659 XTOperatorOr,
00660 XTOperatorAnd,
00661 XTOperatorEq,
00662 XTOperatorNe,
00663 XTOperatorGt,
00664 XTOperatorLt,
00665 XTOperatorLtEq,
00666 XTOperatorGtEq,
00667 XTOperatorPlus,
00668 XTOperatorMinus,
00669 XTOperatorMul,
00670 XTOperatorDiv,
00671 XTOperatorMod,
00672 XTUnion,
00673 XTSlash,
00674 XTDoubleSlash
00675 };
00676
00682 void setXmlns( StringMap* xmlns )
00683 { delete m_xmlnss; m_xmlnss = xmlns; }
00684
00685 Tag* parse( const std::string& expression, unsigned& len, TokenType border = XTNone ) const;
00686
00687 void closePreviousToken( Tag**, Tag**, TokenType&, std::string& ) const;
00688 void addToken( Tag **root, Tag **current, TokenType type, const std::string& token ) const;
00689 void addOperator( Tag **root, Tag **current, Tag* arg, TokenType type,
00690 const std::string& token ) const;
00691 bool addPredicate( Tag **root, Tag **current, Tag* token ) const;
00692
00693 TagList findChildren( const TagList& list, const std::string& name,
00694 const std::string& xmlns = EmptyString ) const;
00695 ConstTagList evaluateTagList( Tag* token ) const;
00696 ConstTagList evaluateUnion( Tag* token ) const;
00697 ConstTagList allDescendants() const;
00698
00699 static TokenType getType( const std::string& c );
00700
00701 static bool isWhitespace( const char c );
00702 bool isNumber() const;
00703
00704 bool evaluateBoolean( Tag* token ) const;
00705 bool evaluatePredicate( Tag* token ) const { return evaluateBoolean( token ); }
00706 bool evaluateEquals( Tag* token ) const;
00707
00708 static void add( ConstTagList& one, const ConstTagList& two );
00709 };
00710
00711 }
00712
00713 #endif // TAG_H__