26 const std::string& xmlns )
32 init( name, value, xmlns );
36 const std::string&
xmlns )
39 init( name, value, xmlns );
43 : m_parent( attr.m_parent ), m_name( attr.m_name ), m_value( attr.m_value ),
44 m_xmlns( attr.m_xmlns ), m_prefix( attr.m_prefix )
48 void Tag::Attribute::init(
const std::string&
name,
const std::string& value,
49 const std::string&
xmlns )
96 if( !m_xmlns.empty() )
100 return m_parent->
xmlns( m_prefix );
107 if( !m_prefix.empty() )
111 return m_parent->
prefix( m_xmlns );
123 if( !m_prefix.empty() )
139 : m_parent( 0 ), m_children( 0 ), m_cdata( 0 ),
140 m_attribs( 0 ), m_nodes( 0 ),
149 Tag::Tag(
Tag* parent,
const std::string& name,
const std::string& cdata )
150 : m_parent( parent ), m_children( 0 ), m_cdata( 0 ),
151 m_attribs( 0 ), m_nodes( 0 ),
164 const std::string& attrib,
165 const std::string& value )
166 : m_parent( 0 ), m_children( 0 ), m_cdata( 0 ),
167 m_attribs( 0 ), m_nodes( 0 ),
168 m_name( name ), m_xmlnss( 0 )
177 const std::string& attrib,
178 const std::string& value )
179 : m_parent( parent ), m_children( 0 ), m_cdata( 0 ),
180 m_attribs( 0 ), m_nodes( 0 ),
181 m_name( name ), m_xmlnss( 0 )
193 : m_parent( 0 ), m_children( 0 ), m_cdata( 0 ), m_attribs( 0 ),
194 m_nodes( 0 ), m_xmlnss( 0 )
199 m_children = tag->m_children;
200 m_cdata = tag->m_cdata;
201 m_attribs = tag->m_attribs;
202 m_nodes = tag->m_nodes;
203 m_name = tag->m_name;
204 m_xmlns = tag->m_xmlns;
205 m_xmlnss = tag->m_xmlnss;
215 AttributeList::iterator it = m_attribs->begin();
216 while( it != m_attribs->end() )
217 (*it++)->m_parent =
this;
222 TagList::iterator it = m_children->begin();
223 while( it != m_children->end() )
224 (*it++)->m_parent =
this;
250 if( m_name != right.m_name || m_xmlns != right.m_xmlns )
253 if( m_cdata && right.m_cdata )
255 StringPList::const_iterator ct = m_cdata->begin();
256 StringPList::const_iterator ct_r = right.m_cdata->begin();
257 while( ct != m_cdata->end() && ct_r != right.m_cdata->end() && *(*ct) == *(*ct_r) )
262 if( ct != m_cdata->end() )
265 else if( m_cdata || right.m_cdata )
268 if( m_children && right.m_children )
270 TagList::const_iterator it = m_children->begin();
271 TagList::const_iterator it_r = right.m_children->begin();
272 while( it != m_children->end() && it_r != right.m_children->end() && *(*it) == *(*it_r) )
277 if( it != m_children->end() )
280 else if( m_children || right.m_children )
283 if( m_attribs && right.m_attribs )
285 AttributeList::const_iterator at = m_attribs->begin();
286 AttributeList::const_iterator at_r = right.m_attribs->begin();
287 while( at != m_attribs->end() && at_r != right.m_attribs->end() && *(*at) == *(*at_r) )
292 if( at != m_attribs->end() )
295 else if( m_attribs || right.m_attribs )
306 std::string
xml =
"<";
307 if( !m_prefix.empty() )
313 if( m_attribs && !m_attribs->empty() )
315 AttributeList::const_iterator it_a = m_attribs->begin();
316 for( ; it_a != m_attribs->end(); ++it_a )
318 xml += (*it_a)->xml();
322 if( !m_nodes || m_nodes->empty() )
327 NodeList::const_iterator it_n = m_nodes->begin();
328 for( ; it_n != m_nodes->end(); ++it_n )
330 switch( (*it_n)->type )
333 xml += (*it_n)->tag->xml();
341 if( !m_prefix.empty() )
367 AttributeList::iterator it = m_attribs->begin();
368 for( ; it != m_attribs->end(); ++it )
370 if( (*it)->name() == attr->
name()
371 && ( (*it)->xmlns() == attr->
xmlns() || (*it)->prefix() == attr->
prefix() ) )
379 m_attribs->push_back( attr );
386 if( name.empty() || value.empty() )
405 return addAttribute( name, util::long2string( value ) );
418 AttributeList::iterator it = m_attribs->begin();
419 for( ; it != m_attribs->end(); ++it )
420 (*it)->m_parent =
this;
429 m_nodes =
new NodeList();
433 m_children->push_back( child );
434 child->m_parent =
this;
435 m_nodes->push_back(
new Node( TypeTag, child ) );
457 m_nodes =
new NodeList();
460 NodeList::iterator it = m_nodes->begin();
461 NodeList::iterator t;
462 while( it != m_nodes->end() )
464 if( (*it)->type == TypeString )
488 m_nodes =
new NodeList();
490 std::string* str =
new std::string( cdata );
491 m_cdata->push_back( str );
492 m_nodes->push_back(
new Node( TypeString, str ) );
502 StringPList::const_iterator it = m_cdata->begin();
503 for( ; it != m_cdata->end(); ++it )
512 return m_children ? *m_children : empty;
518 return m_attribs ? *m_attribs : empty;
544 return xmlns( m_prefix );
547 const std::string&
Tag::xmlns(
const std::string& prefix )
const
556 StringMap::const_iterator it = m_xmlnss->find( prefix );
557 if( it != m_xmlnss->end() )
575 if( xmlns.empty() || !m_xmlnss )
578 StringMap::const_iterator it = m_xmlnss->begin();
579 for( ; it != m_xmlnss->end(); ++it )
581 if( (*it).second == xmlns )
593 AttributeList::const_iterator it = m_attribs->begin();
594 for( ; it != m_attribs->end(); ++it )
595 if( (*it)->name() ==
name )
596 return (*it)->value();
603 if( name.empty() || !m_attribs )
606 AttributeList::const_iterator it = m_attribs->begin();
607 for( ; it != m_attribs->end(); ++it )
608 if( (*it)->name() ==
name )
609 return value.empty() || (*it)->value() == value;
615 const std::string& value )
const
620 return findChild( name, attr, value ) ?
true :
false;
628 TagList::const_iterator it = m_children->begin();
629 while( it != m_children->end() && (*it)->name() !=
name )
631 return it != m_children->end() ? (*it) : 0;
635 const std::string& value )
const
637 if( !m_children || name.empty() )
640 TagList::const_iterator it = m_children->begin();
641 while( it != m_children->end() && ( (*it)->name() != name || !(*it)->hasAttribute( attr, value ) ) )
643 return it != m_children->end() ? (*it) : 0;
648 if( !m_children || name.empty() || cdata.empty() )
651 TagList::const_iterator it = m_children->begin();
652 while( it != m_children->end() && ( (*it)->name() != name
653 || ( !cdata.empty() && (*it)->cdata() !=
cdata ) ) )
655 return it != m_children->end();
660 if( !m_children || attr.empty() )
663 TagList::const_iterator it = m_children->begin();
664 while( it != m_children->end() && !(*it)->hasAttribute( attr, value ) )
666 return it != m_children->end() ? (*it) : 0;
671 Tag* t =
new Tag( m_name );
672 t->m_xmlns = m_xmlns;
673 t->m_prefix = m_prefix;
678 Tag::AttributeList::const_iterator at = m_attribs->begin();
680 for( ; at != m_attribs->end(); ++at )
684 t->m_attribs->push_back( attr );
690 t->m_xmlnss =
new StringMap( *m_xmlnss );
695 Tag::NodeList::const_iterator nt = m_nodes->begin();
696 for( ; nt != m_nodes->end(); ++nt )
698 switch( (*nt)->type )
714 const std::string& xmlns )
const
720 const std::string& xmlns )
const
723 TagList::const_iterator it = list.begin();
724 for( ; it != list.end(); ++it )
726 if( (*it)->name() == name && ( xmlns.empty() || (*it)->xmlns() ==
xmlns ) )
727 ret.push_back( (*it) );
734 if( name.empty() || !m_children || !m_nodes )
738 TagList::iterator it = l.begin();
739 TagList::iterator it2;
740 while( it != l.end() )
743 NodeList::iterator itn = m_nodes->begin();
744 for( ; itn != m_nodes->end(); ++itn )
746 if( (*itn)->type == TypeTag && (*itn)->tag == (*it2) )
749 m_nodes->erase( itn );
753 m_children->remove( (*it2) );
761 m_children->remove( tag );
766 NodeList::iterator it = m_nodes->begin();
767 for( ; it != m_nodes->end(); ++it )
769 if( (*it)->type == TypeTag && (*it)->tag == tag )
772 m_nodes->erase( it );
779 const std::string& xmlns )
781 if( attr.empty() || !m_attribs )
784 AttributeList::iterator it = m_attribs->begin();
785 AttributeList::iterator it2;
786 while( it != m_attribs->end() )
789 if( (*it2)->name() == attr && ( value.empty() || (*it2)->value() == value )
790 && ( xmlns.empty() || (*it2)->xmlns() ==
xmlns ) )
793 m_attribs->erase( it2 );
801 return !l.empty() ? l.front()->cdata() :
EmptyString;
807 return !l.empty() ? l.front() : 0;
813 if( expression ==
"/" || expression ==
"//" )
816 if( m_parent && expression.length() >= 2 && expression[0] ==
'/'
817 && expression[1] !=
'/' )
821 Tag* p = parse( expression, len );
824 l = evaluateTagList( p );
842 add( result, evaluateUnion( token ) );
851 if( tokenChildren.size() )
853 bool predicatesSucceeded =
true;
854 TagList::const_iterator cit = tokenChildren.begin();
855 for( ; cit != tokenChildren.end(); ++cit )
857 if( (*cit)->hasAttribute(
"predicate",
"true" ) )
859 predicatesSucceeded = evaluatePredicate( (*cit) );
860 if( !predicatesSucceeded )
865 bool hasElementChildren =
false;
866 cit = tokenChildren.begin();
867 for( ; cit != tokenChildren.end(); ++cit )
869 if( (*cit)->hasAttribute(
"predicate",
"true" ) ||
870 (*cit)->hasAttribute(
"number",
"true" ) )
873 hasElementChildren =
true;
876 if( m_children && !m_children->empty() )
878 TagList::const_iterator it = m_children->begin();
879 for( ; it != m_children->end(); ++it )
881 add( result, (*it)->evaluateTagList( (*cit) ) );
884 else if( atoi( (*cit)->findAttribute(
TYPE ).c_str() ) == XTDoubleDot && m_parent )
886 (*cit)->addAttribute(
TYPE, XTDot );
887 add( result, m_parent->evaluateTagList( (*cit) ) );
891 if( !hasElementChildren )
892 result.push_back(
this );
897 result.push_back(
this );
911 add( result, evaluateTagList( t ) );
913 ConstTagList::const_iterator it = res2.begin();
914 for( ; it != res2.end(); ++it )
916 add( result, (*it)->evaluateTagList( t ) );
924 if( !tokenChildren.empty() )
926 add( result, evaluateTagList( tokenChildren.front() ) );
929 result.push_back(
this );
938 if( tokenChildren.size() )
940 Tag* testtoken = tokenChildren.front();
941 if( testtoken->name() ==
"*" )
943 add( result, m_parent->evaluateTagList( testtoken ) );
949 t->m_name = m_parent->m_name;
950 add( result, m_parent->evaluateTagList( t ) );
956 result.push_back( m_parent );
968 int pos = atoi( token->
name().c_str() );
970 if( pos > 0 && pos <= (
int)res.size() )
972 ConstTagList::const_iterator it = res.begin();
977 result.push_back( *it );
987 bool Tag::evaluateBoolean( Tag* token )
const
993 TokenType tokenType = (TokenType)atoi( token->findAttribute(
TYPE ).c_str() );
997 if( token->name() ==
"*" && m_attribs && m_attribs->size() )
1003 result = evaluateEquals( token );
1007 case XTOperatorLtEq:
1009 case XTOperatorGtEq:
1017 t->addAttribute(
TYPE, XTDot );
1018 t->addChild( token );
1019 result = !evaluateTagList( t ).empty();
1020 t->removeChild( token );
1031 bool Tag::evaluateEquals( Tag* token )
const
1033 if( !token || token->children().size() != 2 )
1036 bool result =
false;
1037 TagList::const_iterator it = token->children().begin();
1041 TokenType tt1 = (TokenType)atoi( ch1->findAttribute(
TYPE ).c_str() );
1042 TokenType tt2 = (TokenType)atoi( ch2->findAttribute(
TYPE ).c_str() );
1069 result = ( ch1->name() == ch2->name() );
1089 TagList::const_iterator it = m_children->begin();
1090 for( ; it != m_children->end(); ++it )
1092 result.push_back( (*it) );
1093 add( result, (*it)->allDescendants() );
1104 const TagList& l = token->children();
1105 TagList::const_iterator it = l.begin();
1106 for( ; it != l.end(); ++it )
1108 add( result, evaluateTagList( (*it) ) );
1113 void Tag::closePreviousToken( Tag** root, Tag** current, Tag::TokenType& type, std::string& tok )
const
1117 addToken( root, current, type, tok );
1123 Tag* Tag::parse(
const std::string& expression,
unsigned& len, Tag::TokenType border )
const
1126 Tag* current = root;
1135 Tag::TokenType type = XTElement;
1138 for( ; len < expression.length(); ++len )
1140 c = expression[len];
1141 if( type == XTLiteralInside && c !=
'\'' )
1150 closePreviousToken( &root, ¤t, type, token );
1152 if( len < expression.length()-1 && expression[len+1] ==
'/' )
1155 type = XTDoubleSlash;
1165 closePreviousToken( &root, ¤t, type, token );
1169 closePreviousToken( &root, ¤t, type, token );
1170 Tag* t = parse( expression, ++len, XTRightBracket );
1171 if( !addPredicate( &root, ¤t, t ) )
1177 closePreviousToken( &root, ¤t, type, token );
1178 Tag* t = parse( expression, ++len, XTRightParenthesis );
1182 t->addAttribute(
"argument",
"true" );
1183 current->addChild( t );
1193 closePreviousToken( &root, ¤t, type, token );
1197 if( type == XTLiteralInside )
1198 if( expression[len - 2] ==
'\\' )
1199 token[token.length() - 2] = c;
1203 type = XTLiteralInside;
1210 if( token.size() == 1 )
1212 if( len < expression.length()-1 && expression[len+1] ==
'.' )
1231 addToken( &root, ¤t, type,
"*" );
1240 closePreviousToken( &root, ¤t, type, token );
1241 std::string s( 1, c );
1242 Tag::TokenType ttype = getType( s );
1243 if( ttype <= border )
1245 Tag* t = parse( expression, ++len, ttype );
1246 addOperator( &root, ¤t, t, ttype, s );
1247 if( border == XTRightBracket )
1256 if( !token.empty() )
1257 addToken( &root, ¤t, type, token );
1264 void Tag::addToken( Tag **root, Tag **current, Tag::TokenType type,
1265 const std::string& token )
const
1267 Tag* t =
new Tag( token );
1268 if( t->isNumber() && !t->children().size() )
1270 t->addAttribute(
TYPE, type );
1275 (*current)->addChild( t );
1281 *current = *root = t;
1285 void Tag::addOperator( Tag** root, Tag** current, Tag* arg,
1286 Tag::TokenType type,
const std::string& token )
const
1288 Tag* t =
new Tag( token );
1289 t->addAttribute(
TYPE, type );
1292 t->addAttribute(
"operator",
"true" );
1293 t->addChild( *root );
1295 *current = *root = t;
1298 bool Tag::addPredicate( Tag **root, Tag **current, Tag* token )
const
1300 if( !*root || !*current )
1303 if( ( token->isNumber() && !token->children().size() ) || token->name() ==
"+" )
1306 if( !token->hasAttribute(
"operator",
"true" ) )
1308 token->addAttribute(
TYPE, XTInteger );
1310 if( *root == *current )
1317 (*root)->removeChild( *current );
1318 (*root)->addChild( token );
1321 token->addChild( *current );
1326 token->addAttribute(
"predicate",
"true" );
1327 (*current)->addChild( token );
1333 Tag::TokenType Tag::getType(
const std::string& c )
1338 return XTOperatorLt;
1340 return XTOperatorGt;
1342 return XTOperatorMul;
1344 return XTOperatorPlus;
1346 return XTOperatorEq;
1351 bool Tag::isWhitespace(
const char c )
1353 return ( c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20 );
1356 bool Tag::isNumber()
const
1358 if( m_name.empty() )
1361 std::string::size_type l = m_name.length();
1362 std::string::size_type i = 0;
1363 while( i < l && isdigit( m_name[i] ) )
1370 ConstTagList::const_iterator it = two.begin();
1371 for( ; it != two.end(); ++it )
1372 if( std::find( one.begin(), one.end(), (*it) ) == one.end() )
1373 one.push_back( (*it) );
const TagList & children() const
bool checkValidXMLChars(const std::string &data)
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
bool operator==(const Tag &right) const
const std::string xml() const
void clearList(std::list< T * > &L)
const std::string findCData(const std::string &expression) const
bool setPrefix(const std::string &prefix)
void appendEscaped(std::string &target, const std::string &data)
std::list< Attribute * > AttributeList
void setAttributes(const AttributeList &attributes)
Tag * findChildWithAttrib(const std::string &attr, const std::string &value=EmptyString) const
std::list< Tag * > TagList
bool setPrefix(const std::string &prefix)
std::list< const Tag * > ConstTagList
bool setCData(const std::string &cdata)
const Tag * findTag(const std::string &expression) const
Tag(const std::string &name, const std::string &cdata=EmptyString)
void addChild(Tag *child)
const std::string & name() const
const std::string & prefix() const
The namespace for the gloox library.
const std::string & xmlns() const
void removeAttribute(const std::string &attr, const std::string &value=EmptyString, const std::string &xmlns=EmptyString)
Attribute(Tag *parent, const std::string &name, const std::string &value, const std::string &xmlns=EmptyString)
const std::string & findAttribute(const std::string &name) const
bool addCData(const std::string &cdata)
std::map< std::string, std::string > StringMap
bool hasAttribute(const std::string &name, const std::string &value=EmptyString) const
const std::string & prefix() const
const std::string cdata() const
bool setValue(const std::string &value)
std::list< std::string * > StringPList
bool addAttribute(Attribute *attr)
bool hasChild(const std::string &name, const std::string &attr=EmptyString, const std::string &value=EmptyString) const
bool setXmlns(const std::string &xmlns)
const std::string & name() const
TagList findChildren(const std::string &name, const std::string &xmlns=EmptyString) const
const std::string xml() const
bool hasChildWithCData(const std::string &name, const std::string &cdata) const
const AttributeList & attributes() const
Tag * findChild(const std::string &name) const
void addChildCopy(const Tag *child)
ConstTagList findTagList(const std::string &expression) const
const std::string EmptyString
This is an abstraction of an XML element.
void removeChild(const std::string &name, const std::string &xmlns=EmptyString)
const std::string & xmlns() const