gloox  1.0.28
tag.h
1 /*
2  Copyright (c) 2005-2023 by Jakob Schröter <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 #ifdef WANT_XHTMLIM
608  public:
609 #endif
610  enum NodeType
611  {
612  TypeTag,
613  TypeString
614  };
615 
616  struct Node
617  {
618  Node( Tag* _tag ) : type( TypeTag ), tag( _tag ) {}
619  Node( std::string* _str ) : type( TypeString ), str( _str ) {}
620  ~Node() {}
621 
622  NodeType type;
623  union
624  {
625  Tag* tag;
626  std::string* str;
627  };
628  };
629 
630  typedef std::list<Node*> NodeList;
631 
638  const NodeList& nodes() const
639  {
640  static const NodeList empty;
641  return m_nodes ? *m_nodes : empty;
642  }
643 
644 #ifdef WANT_XHTMLIM
645  private:
646 #endif
647  Tag* m_parent;
648  TagList* m_children;
649  StringPList* m_cdata;
650  AttributeList* m_attribs;
651  NodeList* m_nodes;
652  std::string m_name;
653  std::string m_xmlns;
654  StringMap* m_xmlnss;
655  std::string m_prefix;
656 
657  enum TokenType
658  {
659  XTNone,
660  XTLeftParenthesis,
661  XTRightParenthesis,
662  XTNodeSet,
663  XTInteger,
664  XTElement,
665  XTLeftBracket,
666  XTRightBracket,
667  XTFunction,
668  XTAsterisk,
669  XTAttribute,
670  XTLiteralInside,
671  XTLiteral,
672  XTDot,
673  XTDoubleDot,
674  XTOperatorOr,
675  XTOperatorAnd,
676  XTOperatorEq,
677  XTOperatorNe,
678  XTOperatorGt,
679  XTOperatorLt,
680  XTOperatorLtEq,
681  XTOperatorGtEq,
682  XTOperatorPlus,
683  XTOperatorMinus,
684  XTOperatorMul,
685  XTOperatorDiv,
686  XTOperatorMod,
687  XTUnion,
688  XTSlash,
689  XTDoubleSlash
690  };
691 
697  void setXmlns( StringMap* xmlns )
698  { delete m_xmlnss; m_xmlnss = xmlns; }
699 
700  Tag* parse( const std::string& expression, unsigned& len, TokenType border = XTNone ) const;
701 
702  void closePreviousToken( Tag**, Tag**, TokenType&, std::string& ) const;
703  void addToken( Tag **root, Tag **current, TokenType type, const std::string& token ) const;
704  void addOperator( Tag **root, Tag **current, Tag* arg, TokenType type,
705  const std::string& token ) const;
706  bool addPredicate( Tag **root, Tag **current, Tag* token ) const;
707 
708  TagList findChildren( const TagList& list, const std::string& name,
709  const std::string& xmlns = EmptyString ) const;
710  ConstTagList evaluateTagList( Tag* token ) const;
711  ConstTagList evaluateUnion( Tag* token ) const;
712  ConstTagList allDescendants() const;
713 
714  static TokenType getType( const std::string& c );
715 
716  static bool isWhitespace( const char c );
717  bool isNumber() const;
718 
719  bool evaluateBoolean( Tag* token ) const;
720  bool evaluatePredicate( Tag* token ) const { return evaluateBoolean( token ); }
721  bool evaluateEquals( Tag* token ) const;
722 
723  static void add( ConstTagList& one, const ConstTagList& two );
724  };
725 
726 }
727 
728 #endif // TAG_H__
This class implements an XML parser.
Definition: parser.h:35
virtual ~Attribute()
Definition: tag.h:98
bool operator!=(const Attribute &right) const
Definition: tag.h:165
const std::string & value() const
Definition: tag.h:110
bool operator==(const Attribute &right) const
Definition: tag.h:158
const std::string & name() const
Definition: tag.h:104
This is an abstraction of an XML element.
Definition: tag.h:47
bool hasChildWithAttrib(const std::string &attr, const std::string &value=EmptyString) const
Definition: tag.h:475
bool operator!=(const Tag &right) const
Definition: tag.h:582
const std::string & prefix() const
Definition: tag.h:249
Tag * parent() const
Definition: tag.h:526
std::list< Attribute * > AttributeList
Definition: tag.h:187
const std::string & name() const
Definition: tag.h:394
The namespace for the gloox library.
Definition: adhoc.cpp:28
std::list< Tag * > TagList
Definition: tag.h:26
std::list< std::string * > StringPList
Definition: gloox.h:1256
const std::string EmptyString
Definition: gloox.cpp:124
std::list< const Tag * > ConstTagList
Definition: tag.h:36
std::map< std::string, std::string > StringMap
Definition: gloox.h:1261