tag.h
/*
Copyright (c) 2005-2023 by Jakob Schröter <js@camaya.net>
This file is part of the gloox library. http://camaya.net/gloox
This software is distributed under a license. The full license
agreement can be found in the file LICENSE in this distribution.
This software may not be copied, modified, sold or distributed
other than expressed in the named license agreement.
This software is distributed without any warranty.
*/
#ifndef TAG_H__
#define TAG_H__
#include "gloox.h"
#include <string>
#include <list>
#include <utility>
namespace gloox
{
class Tag;
typedef std::list<Tag*> TagList;
typedef std::list<const Tag*> ConstTagList;
class GLOOX_API Tag
{
friend class Parser;
public:
class GLOOX_API Attribute
{
friend class Tag;
public:
Attribute( Tag* parent, const std::string& name, const std::string& value,
const std::string& xmlns = EmptyString );
Attribute( const std::string& name, const std::string& value,
const std::string& xmlns = EmptyString );
Attribute( const Attribute& attr );
virtual ~Attribute() {}
const std::string& name() const { return m_name; }
const std::string& value() const { return m_value; }
bool setValue( const std::string& value );
const std::string xmlns() const;
bool setXmlns( const std::string& xmlns );
bool setPrefix( const std::string& prefix );
const std::string& prefix() const;
const std::string xml() const;
bool operator==( const Attribute &right ) const
{ return m_name == right.m_name && m_value == right.m_value && m_xmlns == right.m_xmlns; }
bool operator!=( const Attribute &right ) const
{ return !( *this == right ); }
operator bool() const { return !m_name.empty(); }
private:
void init( const std::string& name, const std::string& value,
const std::string& xmlns );
Tag* m_parent;
std::string m_name;
std::string m_value;
std::string m_xmlns;
std::string m_prefix;
};
typedef std::list<Attribute*> AttributeList;
Tag( const std::string& name, const std::string& cdata = EmptyString );
Tag( Tag* parent, const std::string& name, const std::string& cdata = EmptyString );
Tag( const std::string& name, const std::string& attrib, const std::string& value );
Tag( Tag* parent, const std::string& name, const std::string& attrib, const std::string& value );
virtual ~Tag();
const std::string xml() const;
bool setPrefix( const std::string& prefix );
const std::string& prefix() const { return m_prefix; }
const std::string& prefix( const std::string& xmlns ) const;
/* *
* Adds an XML namespace declaration to the Tag. If @b def is false, a unique prefix will
* be created, else the default namespace is set (no prefix).
* @param xmlns The namespace value.
* @param def If @b true, this sets the default namespace; if @b false, a unique namespace
* prefix will be created (unless one already exists for the namespace) and used for
* all subsequent references to the same namespace.
* @since 1.0
*/
// const std::string addXmlns( const std::string& xmlns, bool def );
bool setXmlns( const std::string& xmlns, const std::string& prefix = EmptyString );
const std::string xmlns() const;
const std::string xmlns( const std::string& prefix ) const;
bool addAttribute( Attribute* attr );
bool addAttribute( const std::string& name, const std::string& value );
bool addAttribute( const std::string& name, int value );
bool addAttribute( const std::string& name, long value );
void setAttributes( const AttributeList& attributes );
void addChild( Tag* child );
void addChildCopy( const Tag* child );
bool setCData( const std::string& cdata );
bool addCData( const std::string& cdata );
const std::string& name() const { return m_name; }
const std::string cdata() const;
const AttributeList& attributes() const;
const TagList& children() const;
const std::string& findAttribute( const std::string& name ) const;
bool hasAttribute( const std::string& name, const std::string& value = EmptyString ) const;
Tag* findChild( const std::string& name ) const;
Tag* findChild( const std::string& name, const std::string& attr,
const std::string& value = EmptyString ) const;
bool hasChild( const std::string& name, const std::string& attr = EmptyString,
const std::string& value = EmptyString ) const;
Tag* findChildWithAttrib( const std::string& attr, const std::string& value = EmptyString ) const;
inline bool hasChildWithAttrib( const std::string& attr,
const std::string& value = EmptyString ) const
{ return findChildWithAttrib( attr, value ) ? true : false; }
TagList findChildren( const std::string& name, const std::string& xmlns = EmptyString ) const;
void removeChild( const std::string& name, const std::string& xmlns = EmptyString );
void removeChild( Tag* tag );
void removeAttribute( const std::string& attr, const std::string& value = EmptyString,
const std::string& xmlns = EmptyString );
bool hasChildWithCData( const std::string& name, const std::string& cdata ) const;
Tag* parent() const { return m_parent; }
Tag* clone() const;
const std::string findCData( const std::string& expression ) const;
const Tag* findTag( const std::string& expression ) const;
ConstTagList findTagList( const std::string& expression ) const;
bool operator==( const Tag &right ) const;
bool operator!=( const Tag &right ) const { return !( *this == right ); }
operator bool() const { return !m_name.empty(); }
private:
Tag( Tag* tag );
enum XPathError
{
XPNoError,
XPExpectedLeftOperand,
XPUnexpectedToken
};
#ifdef WANT_XHTMLIM
public:
#endif
enum NodeType
{
TypeTag,
TypeString
};
struct Node
{
Node( Tag* _tag ) : type( TypeTag ), tag( _tag ) {}
Node( std::string* _str ) : type( TypeString ), str( _str ) {}
~Node() {}
NodeType type;
union
{
Tag* tag;
std::string* str;
};
};
typedef std::list<Node*> NodeList;
const NodeList& nodes() const
{
static const NodeList empty;
return m_nodes ? *m_nodes : empty;
}
#ifdef WANT_XHTMLIM
private:
#endif
Tag* m_parent;
TagList* m_children;
StringPList* m_cdata;
AttributeList* m_attribs;
NodeList* m_nodes;
std::string m_name;
std::string m_xmlns;
StringMap* m_xmlnss;
std::string m_prefix;
enum TokenType
{
XTNone,
XTLeftParenthesis,
XTRightParenthesis,
XTNodeSet,
XTInteger,
XTElement,
XTLeftBracket,
XTRightBracket,
XTFunction,
XTAsterisk,
XTAttribute,
XTLiteralInside,
XTLiteral,
XTDot,
XTDoubleDot,
XTOperatorOr,
XTOperatorAnd,
XTOperatorEq,
XTOperatorNe,
XTOperatorGt,
XTOperatorLt,
XTOperatorLtEq,
XTOperatorGtEq,
XTOperatorPlus,
XTOperatorMinus,
XTOperatorMul,
XTOperatorDiv,
XTOperatorMod,
XTUnion,
XTSlash,
XTDoubleSlash
};
void setXmlns( StringMap* xmlns )
{ delete m_xmlnss; m_xmlnss = xmlns; }
Tag* parse( const std::string& expression, unsigned& len, TokenType border = XTNone ) const;
void closePreviousToken( Tag**, Tag**, TokenType&, std::string& ) const;
void addToken( Tag **root, Tag **current, TokenType type, const std::string& token ) const;
void addOperator( Tag **root, Tag **current, Tag* arg, TokenType type,
const std::string& token ) const;
bool addPredicate( Tag **root, Tag **current, Tag* token ) const;
TagList findChildren( const TagList& list, const std::string& name,
const std::string& xmlns = EmptyString ) const;
ConstTagList evaluateTagList( Tag* token ) const;
ConstTagList evaluateUnion( Tag* token ) const;
ConstTagList allDescendants() const;
static TokenType getType( const std::string& c );
static bool isWhitespace( const char c );
bool isNumber() const;
bool evaluateBoolean( Tag* token ) const;
bool evaluatePredicate( Tag* token ) const { return evaluateBoolean( token ); }
bool evaluateEquals( Tag* token ) const;
static void add( ConstTagList& one, const ConstTagList& two );
};
}
#endif // TAG_H__
gloox::Tag::Attribute::~Attribute
virtual ~Attribute()
Definition tag.h:98
gloox::Tag::Attribute::name
const std::string & name() const
Definition tag.h:104
gloox::Tag::Attribute::value
const std::string & value() const
Definition tag.h:110
gloox::Tag::Attribute::operator!=
bool operator!=(const Attribute &right) const
Definition tag.h:165
gloox::Tag::Attribute::xmlns
const std::string xmlns() const
Definition tag.cpp:95
gloox::Tag::Attribute::operator==
bool operator==(const Attribute &right) const
Definition tag.h:158
gloox::Tag::Attribute::Attribute
Attribute(Tag *parent, const std::string &name, const std::string &value, const std::string &xmlns=EmptyString)
Definition tag.cpp:26
gloox::Tag
This is an abstraction of an XML element.
Definition tag.h:47
gloox::Tag::hasChildWithAttrib
bool hasChildWithAttrib(const std::string &attr, const std::string &value=EmptyString) const
Definition tag.h:475
gloox::Tag::findChildWithAttrib
Tag * findChildWithAttrib(const std::string &attr, const std::string &value=EmptyString) const
Definition tag.cpp:659
gloox::Tag::name
const std::string & name() const
Definition tag.h:394
gloox::Tag::operator!=
bool operator!=(const Tag &right) const
Definition tag.h:582
gloox::Tag::setPrefix
bool setPrefix(const std::string &prefix)
Definition tag.cpp:565
gloox::Tag::xmlns
const std::string xmlns() const
Definition tag.cpp:543
gloox::Tag::AttributeList
std::list< Attribute * > AttributeList
Definition tag.h:187
gloox::Tag::cdata
const std::string cdata() const
Definition tag.cpp:497
gloox::Tag::parent
Tag * parent() const
Definition tag.h:526
gloox::Tag::Tag
Tag(const std::string &name, const std::string &cdata=EmptyString)
Definition tag.cpp:139
gloox::Tag::xml
const std::string xml() const
Definition tag.cpp:302
gloox::Tag::setXmlns
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition tag.cpp:522
gloox::Tag::prefix
const std::string & prefix() const
Definition tag.h:249
gloox::PubSub::NodeType
NodeType
Definition pubsub.h:36
gloox
The namespace for the gloox library.
Definition adhoc.cpp:28
gloox::TagList
std::list< Tag * > TagList
Definition tag.h:31
gloox::StringPList
std::list< std::string * > StringPList
Definition gloox.h:1256
gloox::EmptyString
const std::string EmptyString
Definition gloox.cpp:124
gloox::ConstTagList
std::list< const Tag * > ConstTagList
Definition tag.h:36
gloox::StringMap
std::map< std::string, std::string > StringMap
Definition gloox.h:1261