gloox
1.0
|
00001 /* 00002 Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net> 00003 This file is part of the gloox library. http://camaya.net/gloox 00004 00005 This software is distributed under a license. The full license 00006 agreement can be found in the file LICENSE in this distribution. 00007 This software may not be copied, modified, sold or distributed 00008 other than expressed in the named license agreement. 00009 00010 This software is distributed without any warranty. 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 * Adds an XML namespace declaration to the Tag. If @b def is false, a unique prefix will 00260 * be created, else the default namespace is set (no prefix). 00261 * @param xmlns The namespace value. 00262 * @param def If @b true, this sets the default namespace; if @b false, a unique namespace 00263 * prefix will be created (unless one already exists for the namespace) and used for 00264 * all subsequent references to the same namespace. 00265 * @since 1.0 00266 */ 00267 // const std::string addXmlns( const std::string& xmlns, bool def ); 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__