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
00194 Tag( const std::string& name, const std::string& cdata = EmptyString );
00195
00203 Tag( Tag* parent, const std::string& name, const std::string& cdata = EmptyString );
00204
00211 Tag( const std::string& name, const std::string& attrib, const std::string& value );
00212
00221 Tag( Tag* parent, const std::string& name, const std::string& attrib, const std::string& value );
00222
00226 virtual ~Tag();
00227
00233 const std::string xml() const;
00234
00242 bool setPrefix( const std::string& prefix );
00243
00249 const std::string& prefix() const { return m_prefix; }
00250
00256 const std::string& prefix( const std::string& xmlns ) const;
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00278 bool setXmlns( const std::string& xmlns, const std::string& prefix = EmptyString );
00279
00286 const std::string& xmlns() const;
00287
00305 const std::string& xmlns( const std::string& prefix ) const;
00306
00317 bool addAttribute( Attribute* attr );
00318
00327 bool addAttribute( const std::string& name, const std::string& value );
00328
00338 bool addAttribute( const std::string& name, int value );
00339
00349 bool addAttribute( const std::string& name, long value );
00350
00359 void setAttributes( const AttributeList& attributes );
00360
00365 void addChild( Tag* child );
00366
00372 void addChildCopy( const Tag* child );
00373
00380 bool setCData( const std::string& cdata );
00381
00388 bool addCData( const std::string& cdata );
00389
00394 const std::string& name() const { return m_name; }
00395
00400 const std::string cdata() const;
00401
00406 const AttributeList& attributes() const;
00407
00412 const TagList& children() const;
00413
00419 const std::string& findAttribute( const std::string& name ) const;
00420
00427 bool hasAttribute( const std::string& name, const std::string& value = EmptyString ) const;
00428
00435 Tag* findChild( const std::string& name ) const;
00436
00445 Tag* findChild( const std::string& name, const std::string& attr,
00446 const std::string& value = EmptyString ) const;
00447
00456 bool hasChild( const std::string& name, const std::string& attr = EmptyString,
00457 const std::string& value = EmptyString ) const;
00458
00466 Tag* findChildWithAttrib( const std::string& attr, const std::string& value = EmptyString ) const;
00467
00475 inline bool hasChildWithAttrib( const std::string& attr,
00476 const std::string& value = EmptyString ) const
00477 { return findChildWithAttrib( attr, value ) ? true : false; }
00478
00487 TagList findChildren( const std::string& name, const std::string& xmlns = EmptyString ) const;
00488
00495 void removeChild( const std::string& name, const std::string& xmlns = EmptyString );
00496
00502 void removeChild( Tag* tag );
00503
00510 void removeAttribute( const std::string& attr, const std::string& value = EmptyString,
00511 const std::string& xmlns = EmptyString );
00512
00520 bool hasChildWithCData( const std::string& name, const std::string& cdata ) const;
00521
00526 Tag* parent() const { return m_parent; }
00527
00533 Tag* clone() const;
00534
00545 const std::string findCData( const std::string& expression ) const;
00546
00557 const Tag* findTag( const std::string& expression ) const;
00558
00568 ConstTagList findTagList( const std::string& expression ) const;
00569
00575 bool operator==( const Tag &right ) const;
00576
00582 bool operator!=( const Tag &right ) const { return !( *this == right ); }
00583
00587 operator bool() const { return !m_name.empty(); }
00588
00589 private:
00595 Tag( Tag* tag );
00596
00600 enum XPathError
00601 {
00602 XPNoError,
00603 XPExpectedLeftOperand,
00604 XPUnexpectedToken
00605 };
00606
00607 enum NodeType
00608 {
00609 TypeTag,
00610 TypeString
00611 };
00612
00613 struct Node
00614 {
00615 Node( NodeType _type, Tag* _tag ) : type( _type ), tag( _tag ) {}
00616 Node( NodeType _type, std::string* _str ) : type( _type ), str( _str ) {}
00617 ~Node() {}
00618
00619 NodeType type;
00620 union
00621 {
00622 Tag* tag;
00623 std::string* str;
00624 };
00625 };
00626
00627 typedef std::list<Node*> NodeList;
00628
00629 Tag* m_parent;
00630 TagList* m_children;
00631 StringPList* m_cdata;
00632 AttributeList* m_attribs;
00633 NodeList* m_nodes;
00634 std::string m_name;
00635 std::string m_xmlns;
00636 StringMap* m_xmlnss;
00637 std::string m_prefix;
00638
00639 enum TokenType
00640 {
00641 XTNone,
00642 XTLeftParenthesis,
00643 XTRightParenthesis,
00644 XTNodeSet,
00645 XTInteger,
00646 XTElement,
00647 XTLeftBracket,
00648 XTRightBracket,
00649 XTFunction,
00650 XTAsterisk,
00651 XTAttribute,
00652 XTLiteralInside,
00653 XTLiteral,
00654 XTDot,
00655 XTDoubleDot,
00656 XTOperatorOr,
00657 XTOperatorAnd,
00658 XTOperatorEq,
00659 XTOperatorNe,
00660 XTOperatorGt,
00661 XTOperatorLt,
00662 XTOperatorLtEq,
00663 XTOperatorGtEq,
00664 XTOperatorPlus,
00665 XTOperatorMinus,
00666 XTOperatorMul,
00667 XTOperatorDiv,
00668 XTOperatorMod,
00669 XTUnion,
00670 XTSlash,
00671 XTDoubleSlash
00672 };
00673
00679 void setXmlns( StringMap* xmlns )
00680 { delete m_xmlnss; m_xmlnss = xmlns; }
00681
00682 Tag* parse( const std::string& expression, unsigned& len, TokenType border = XTNone ) const;
00683
00684 void closePreviousToken( Tag**, Tag**, TokenType&, std::string& ) const;
00685 void addToken( Tag **root, Tag **current, TokenType type, const std::string& token ) const;
00686 void addOperator( Tag **root, Tag **current, Tag* arg, TokenType type,
00687 const std::string& token ) const;
00688 bool addPredicate( Tag **root, Tag **current, Tag* token ) const;
00689
00690 TagList findChildren( const TagList& list, const std::string& name,
00691 const std::string& xmlns = EmptyString ) const;
00692 ConstTagList evaluateTagList( Tag* token ) const;
00693 ConstTagList evaluateUnion( Tag* token ) const;
00694 ConstTagList allDescendants() const;
00695
00696 static TokenType getType( const std::string& c );
00697
00698 static bool isWhitespace( const char c );
00699 bool isNumber() const;
00700
00701 bool evaluateBoolean( Tag* token ) const;
00702 bool evaluatePredicate( Tag* token ) const { return evaluateBoolean( token ); }
00703 bool evaluateEquals( Tag* token ) const;
00704
00705 static void add( ConstTagList& one, const ConstTagList& two );
00706 };
00707
00708 }
00709
00710 #endif // TAG_H__