gloox  1.0
tag.h
1 /*
2  Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 #ifndef TAG_H__
15 #define TAG_H__
16 
17 #include "gloox.h"
18 
19 #include <string>
20 #include <list>
21 #include <utility>
22 
23 namespace gloox
24 {
25 
26  class Tag;
27 
31  typedef std::list<Tag*> TagList;
32 
36  typedef std::list<const Tag*> ConstTagList;
37 
46  class GLOOX_API Tag
47  {
48 
49  friend class Parser;
50 
51  public:
52 
59  class GLOOX_API Attribute
60  {
61 
62  friend class Tag;
63 
64  public:
77  Attribute( Tag* parent, const std::string& name, const std::string& value,
78  const std::string& xmlns = EmptyString );
79 
86  Attribute( const std::string& name, const std::string& value,
87  const std::string& xmlns = EmptyString );
88 
93  Attribute( const Attribute& attr );
94 
98  virtual ~Attribute() {}
99 
104  const std::string& name() const { return m_name; }
105 
110  const std::string& value() const { return m_value; }
111 
118  bool setValue( const std::string& value );
119 
124  const std::string& xmlns() const;
125 
132  bool setXmlns( const std::string& xmlns );
133 
140  bool setPrefix( const std::string& prefix );
141 
146  const std::string& prefix() const;
147 
152  const std::string xml() const;
153 
158  bool operator==( const Attribute &right ) const
159  { return m_name == right.m_name && m_value == right.m_value && m_xmlns == right.m_xmlns; }
160 
165  bool operator!=( const Attribute &right ) const
166  { return !( *this == right ); }
167 
171  operator bool() const { return !m_name.empty(); }
172 
173  private:
174  void init( const std::string& name, const std::string& value,
175  const std::string& xmlns );
176  Tag* m_parent;
177  std::string m_name;
178  std::string m_value;
179  std::string m_xmlns;
180  std::string m_prefix;
181 
182  };
183 
187  typedef std::list<Attribute*> AttributeList;
188 
194  Tag( const std::string& name, const std::string& cdata = EmptyString );
195 
203  Tag( Tag* parent, const std::string& name, const std::string& cdata = EmptyString );
204 
211  Tag( const std::string& name, const std::string& attrib, const std::string& value );
212 
221  Tag( Tag* parent, const std::string& name, const std::string& attrib, const std::string& value );
222 
226  virtual ~Tag();
227 
233  const std::string xml() const;
234 
242  bool setPrefix( const std::string& prefix );
243 
249  const std::string& prefix() const { return m_prefix; }
250 
256  const std::string& prefix( const std::string& xmlns ) const;
257 
258  /* *
259  * Adds an XML namespace declaration to the Tag. If @b def is false, a unique prefix will
260  * be created, else the default namespace is set (no prefix).
261  * @param xmlns The namespace value.
262  * @param def If @b true, this sets the default namespace; if @b false, a unique namespace
263  * prefix will be created (unless one already exists for the namespace) and used for
264  * all subsequent references to the same namespace.
265  * @since 1.0
266  */
267 // const std::string addXmlns( const std::string& xmlns, bool def );
268 
278  bool setXmlns( const std::string& xmlns, const std::string& prefix = EmptyString );
279 
286  const std::string& xmlns() const;
287 
305  const std::string& xmlns( const std::string& prefix ) const;
306 
317  bool addAttribute( Attribute* attr );
318 
327  bool addAttribute( const std::string& name, const std::string& value );
328 
338  bool addAttribute( const std::string& name, int value );
339 
349  bool addAttribute( const std::string& name, long value );
350 
359  void setAttributes( const AttributeList& attributes );
360 
365  void addChild( Tag* child );
366 
372  void addChildCopy( const Tag* child );
373 
380  bool setCData( const std::string& cdata );
381 
388  bool addCData( const std::string& cdata );
389 
394  const std::string& name() const { return m_name; }
395 
400  const std::string cdata() const;
401 
406  const AttributeList& attributes() const;
407 
412  const TagList& children() const;
413 
419  const std::string& findAttribute( const std::string& name ) const;
420 
427  bool hasAttribute( const std::string& name, const std::string& value = EmptyString ) const;
428 
435  Tag* findChild( const std::string& name ) const;
436 
445  Tag* findChild( const std::string& name, const std::string& attr,
446  const std::string& value = EmptyString ) const;
447 
456  bool hasChild( const std::string& name, const std::string& attr = EmptyString,
457  const std::string& value = EmptyString ) const;
458 
466  Tag* findChildWithAttrib( const std::string& attr, const std::string& value = EmptyString ) const;
467 
475  inline bool hasChildWithAttrib( const std::string& attr,
476  const std::string& value = EmptyString ) const
477  { return findChildWithAttrib( attr, value ) ? true : false; }
478 
487  TagList findChildren( const std::string& name, const std::string& xmlns = EmptyString ) const;
488 
495  void removeChild( const std::string& name, const std::string& xmlns = EmptyString );
496 
502  void removeChild( Tag* tag );
503 
510  void removeAttribute( const std::string& attr, const std::string& value = EmptyString,
511  const std::string& xmlns = EmptyString );
512 
520  bool hasChildWithCData( const std::string& name, const std::string& cdata ) const;
521 
526  Tag* parent() const { return m_parent; }
527 
533  Tag* clone() const;
534 
545  const std::string findCData( const std::string& expression ) const;
546 
557  const Tag* findTag( const std::string& expression ) const;
558 
568  ConstTagList findTagList( const std::string& expression ) const;
569 
575  bool operator==( const Tag &right ) const;
576 
582  bool operator!=( const Tag &right ) const { return !( *this == right ); }
583 
587  operator bool() const { return !m_name.empty(); }
588 
589  private:
595  Tag( Tag* tag );
596 
600  enum XPathError
601  {
602  XPNoError,
603  XPExpectedLeftOperand,
604  XPUnexpectedToken
605  };
606 
607  enum NodeType
608  {
609  TypeTag,
610  TypeString
611  };
612 
613  struct Node
614  {
615  Node( NodeType _type, Tag* _tag ) : type( _type ), tag( _tag ) {}
616  Node( NodeType _type, std::string* _str ) : type( _type ), str( _str ) {}
617  ~Node() {}
618 
619  NodeType type;
620  union
621  {
622  Tag* tag;
623  std::string* str;
624  };
625  };
626 
627  typedef std::list<Node*> NodeList;
628 
629  Tag* m_parent;
630  TagList* m_children;
631  StringPList* m_cdata;
632  AttributeList* m_attribs;
633  NodeList* m_nodes;
634  std::string m_name;
635  std::string m_xmlns;
636  StringMap* m_xmlnss;
637  std::string m_prefix;
638 
639  enum TokenType
640  {
641  XTNone,
642  XTLeftParenthesis,
643  XTRightParenthesis,
644  XTNodeSet,
645  XTInteger,
646  XTElement,
647  XTLeftBracket,
648  XTRightBracket,
649  XTFunction,
650  XTAsterisk,
651  XTAttribute,
652  XTLiteralInside,
653  XTLiteral,
654  XTDot,
655  XTDoubleDot,
656  XTOperatorOr,
657  XTOperatorAnd,
658  XTOperatorEq,
659  XTOperatorNe,
660  XTOperatorGt,
661  XTOperatorLt,
662  XTOperatorLtEq,
663  XTOperatorGtEq,
664  XTOperatorPlus,
665  XTOperatorMinus,
666  XTOperatorMul,
667  XTOperatorDiv,
668  XTOperatorMod,
669  XTUnion,
670  XTSlash,
671  XTDoubleSlash
672  };
673 
679  void setXmlns( StringMap* xmlns )
680  { delete m_xmlnss; m_xmlnss = xmlns; }
681 
682  Tag* parse( const std::string& expression, unsigned& len, TokenType border = XTNone ) const;
683 
684  void closePreviousToken( Tag**, Tag**, TokenType&, std::string& ) const;
685  void addToken( Tag **root, Tag **current, TokenType type, const std::string& token ) const;
686  void addOperator( Tag **root, Tag **current, Tag* arg, TokenType type,
687  const std::string& token ) const;
688  bool addPredicate( Tag **root, Tag **current, Tag* token ) const;
689 
690  TagList findChildren( const TagList& list, const std::string& name,
691  const std::string& xmlns = EmptyString ) const;
692  ConstTagList evaluateTagList( Tag* token ) const;
693  ConstTagList evaluateUnion( Tag* token ) const;
694  ConstTagList allDescendants() const;
695 
696  static TokenType getType( const std::string& c );
697 
698  static bool isWhitespace( const char c );
699  bool isNumber() const;
700 
701  bool evaluateBoolean( Tag* token ) const;
702  bool evaluatePredicate( Tag* token ) const { return evaluateBoolean( token ); }
703  bool evaluateEquals( Tag* token ) const;
704 
705  static void add( ConstTagList& one, const ConstTagList& two );
706  };
707 
708 }
709 
710 #endif // TAG_H__