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 )
484 m_nodes =
new NodeList();
486 std::string* str =
new std::string( cdata );
487 m_cdata->push_back( str );
488 m_nodes->push_back(
new Node( TypeString, str ) );
498 StringPList::const_iterator it = m_cdata->begin();
499 for( ; it != m_cdata->end(); ++it )
508 return m_children ? *m_children : empty;
514 return m_attribs ? *m_attribs : empty;
540 return xmlns( m_prefix );
543 const std::string&
Tag::xmlns(
const std::string& prefix )
const
552 StringMap::const_iterator it = m_xmlnss->find( prefix );
553 if( it != m_xmlnss->end() )
571 if( xmlns.empty() || !m_xmlnss )
574 StringMap::const_iterator it = m_xmlnss->begin();
575 for( ; it != m_xmlnss->end(); ++it )
577 if( (*it).second == xmlns )
589 AttributeList::const_iterator it = m_attribs->begin();
590 for( ; it != m_attribs->end(); ++it )
591 if( (*it)->name() ==
name )
592 return (*it)->value();
599 if( name.empty() || !m_attribs )
602 AttributeList::const_iterator it = m_attribs->begin();
603 for( ; it != m_attribs->end(); ++it )
604 if( (*it)->name() ==
name )
605 return value.empty() || (*it)->value() == value;
611 const std::string& value )
const
616 return findChild( name, attr, value ) ?
true :
false;
624 TagList::const_iterator it = m_children->begin();
625 while( it != m_children->end() && (*it)->name() !=
name )
627 return it != m_children->end() ? (*it) : 0;
631 const std::string& value )
const
633 if( !m_children || name.empty() )
636 TagList::const_iterator it = m_children->begin();
637 while( it != m_children->end() && ( (*it)->name() != name || !(*it)->hasAttribute( attr, value ) ) )
639 return it != m_children->end() ? (*it) : 0;
644 if( !m_children || name.empty() || cdata.empty() )
647 TagList::const_iterator it = m_children->begin();
648 while( it != m_children->end() && ( (*it)->name() != name
649 || ( !cdata.empty() && (*it)->cdata() !=
cdata ) ) )
651 return it != m_children->end();
656 if( !m_children || attr.empty() )
659 TagList::const_iterator it = m_children->begin();
660 while( it != m_children->end() && !(*it)->hasAttribute( attr, value ) )
662 return it != m_children->end() ? (*it) : 0;
667 Tag* t =
new Tag( m_name );
668 t->m_xmlns = m_xmlns;
669 t->m_prefix = m_prefix;
674 Tag::AttributeList::const_iterator at = m_attribs->begin();
676 for( ; at != m_attribs->end(); ++at )
680 t->m_attribs->push_back( attr );
686 t->m_xmlnss =
new StringMap( *m_xmlnss );
691 Tag::NodeList::const_iterator nt = m_nodes->begin();
692 for( ; nt != m_nodes->end(); ++nt )
694 switch( (*nt)->type )
710 const std::string& xmlns )
const
716 const std::string& xmlns )
const
719 TagList::const_iterator it = list.begin();
720 for( ; it != list.end(); ++it )
722 if( (*it)->name() == name && ( xmlns.empty() || (*it)->xmlns() ==
xmlns ) )
723 ret.push_back( (*it) );
730 if( name.empty() || !m_children || !m_nodes )
734 TagList::iterator it = l.begin();
735 TagList::iterator it2;
736 while( it != l.end() )
739 NodeList::iterator itn = m_nodes->begin();
740 for( ; itn != m_nodes->end(); ++itn )
742 if( (*itn)->type == TypeTag && (*itn)->tag == (*it2) )
745 m_nodes->erase( itn );
749 m_children->remove( (*it2) );
757 m_children->remove( tag );
762 NodeList::iterator it = m_nodes->begin();
763 for( ; it != m_nodes->end(); ++it )
765 if( (*it)->type == TypeTag && (*it)->tag == tag )
768 m_nodes->erase( it );
775 const std::string& xmlns )
777 if( attr.empty() || !m_attribs )
780 AttributeList::iterator it = m_attribs->begin();
781 AttributeList::iterator it2;
782 while( it != m_attribs->end() )
785 if( (*it2)->name() == attr && ( value.empty() || (*it2)->value() == value )
786 && ( xmlns.empty() || (*it2)->xmlns() ==
xmlns ) )
789 m_attribs->erase( it2 );
797 return !l.empty() ? l.front()->cdata() :
EmptyString;
803 return !l.empty() ? l.front() : 0;
809 if( expression ==
"/" || expression ==
"//" )
812 if( m_parent && expression.length() >= 2 && expression[0] ==
'/'
813 && expression[1] !=
'/' )
817 Tag* p = parse( expression, len );
820 l = evaluateTagList( p );
838 add( result, evaluateUnion( token ) );
847 if( tokenChildren.size() )
849 bool predicatesSucceeded =
true;
850 TagList::const_iterator cit = tokenChildren.begin();
851 for( ; cit != tokenChildren.end(); ++cit )
853 if( (*cit)->hasAttribute(
"predicate",
"true" ) )
855 predicatesSucceeded = evaluatePredicate( (*cit) );
856 if( !predicatesSucceeded )
861 bool hasElementChildren =
false;
862 cit = tokenChildren.begin();
863 for( ; cit != tokenChildren.end(); ++cit )
865 if( (*cit)->hasAttribute(
"predicate",
"true" ) ||
866 (*cit)->hasAttribute(
"number",
"true" ) )
869 hasElementChildren =
true;
872 if( m_children && !m_children->empty() )
874 TagList::const_iterator it = m_children->begin();
875 for( ; it != m_children->end(); ++it )
877 add( result, (*it)->evaluateTagList( (*cit) ) );
880 else if( atoi( (*cit)->findAttribute(
TYPE ).c_str() ) == XTDoubleDot && m_parent )
882 (*cit)->addAttribute(
TYPE, XTDot );
883 add( result, m_parent->evaluateTagList( (*cit) ) );
887 if( !hasElementChildren )
888 result.push_back(
this );
893 result.push_back(
this );
907 add( result, evaluateTagList( t ) );
909 ConstTagList::const_iterator it = res2.begin();
910 for( ; it != res2.end(); ++it )
912 add( result, (*it)->evaluateTagList( t ) );
920 if( !tokenChildren.empty() )
922 add( result, evaluateTagList( tokenChildren.front() ) );
925 result.push_back(
this );
934 if( tokenChildren.size() )
936 Tag* testtoken = tokenChildren.front();
937 if( testtoken->name() ==
"*" )
939 add( result, m_parent->evaluateTagList( testtoken ) );
945 t->m_name = m_parent->m_name;
946 add( result, m_parent->evaluateTagList( t ) );
952 result.push_back( m_parent );
964 int pos = atoi( token->
name().c_str() );
966 if( pos > 0 && pos <= (
int)res.size() )
968 ConstTagList::const_iterator it = res.begin();
973 result.push_back( *it );
983 bool Tag::evaluateBoolean( Tag* token )
const
989 TokenType tokenType = (TokenType)atoi( token->findAttribute(
TYPE ).c_str() );
993 if( token->name() ==
"*" && m_attribs && m_attribs->size() )
999 result = evaluateEquals( token );
1003 case XTOperatorLtEq:
1005 case XTOperatorGtEq:
1013 t->addAttribute(
TYPE, XTDot );
1014 t->addChild( token );
1015 result = !evaluateTagList( t ).empty();
1016 t->removeChild( token );
1027 bool Tag::evaluateEquals( Tag* token )
const
1029 if( !token || token->children().size() != 2 )
1032 bool result =
false;
1033 TagList::const_iterator it = token->children().begin();
1037 TokenType tt1 = (TokenType)atoi( ch1->findAttribute(
TYPE ).c_str() );
1038 TokenType tt2 = (TokenType)atoi( ch2->findAttribute(
TYPE ).c_str() );
1065 result = ( ch1->name() == ch2->name() );
1085 TagList::const_iterator it = m_children->begin();
1086 for( ; it != m_children->end(); ++it )
1088 result.push_back( (*it) );
1089 add( result, (*it)->allDescendants() );
1100 const TagList& l = token->children();
1101 TagList::const_iterator it = l.begin();
1102 for( ; it != l.end(); ++it )
1104 add( result, evaluateTagList( (*it) ) );
1109 void Tag::closePreviousToken( Tag** root, Tag** current, Tag::TokenType& type, std::string& tok )
const
1113 addToken( root, current, type, tok );
1119 Tag* Tag::parse(
const std::string& expression,
unsigned& len, Tag::TokenType border )
const
1122 Tag* current = root;
1131 Tag::TokenType type = XTElement;
1134 for( ; len < expression.length(); ++len )
1136 c = expression[len];
1137 if( type == XTLiteralInside && c !=
'\'' )
1146 closePreviousToken( &root, ¤t, type, token );
1148 if( len < expression.length()-1 && expression[len+1] ==
'/' )
1151 type = XTDoubleSlash;
1161 closePreviousToken( &root, ¤t, type, token );
1165 closePreviousToken( &root, ¤t, type, token );
1166 Tag* t = parse( expression, ++len, XTRightBracket );
1167 if( !addPredicate( &root, ¤t, t ) )
1173 closePreviousToken( &root, ¤t, type, token );
1174 Tag* t = parse( expression, ++len, XTRightParenthesis );
1178 t->addAttribute(
"argument",
"true" );
1179 current->addChild( t );
1189 closePreviousToken( &root, ¤t, type, token );
1193 if( type == XTLiteralInside )
1194 if( expression[len - 2] ==
'\\' )
1195 token[token.length() - 2] = c;
1199 type = XTLiteralInside;
1206 if( token.size() == 1 )
1208 if( len < expression.length()-1 && expression[len+1] ==
'.' )
1227 addToken( &root, ¤t, type,
"*" );
1236 closePreviousToken( &root, ¤t, type, token );
1237 std::string s( 1, c );
1238 Tag::TokenType ttype = getType( s );
1239 if( ttype <= border )
1241 Tag* t = parse( expression, ++len, ttype );
1242 addOperator( &root, ¤t, t, ttype, s );
1243 if( border == XTRightBracket )
1252 if( !token.empty() )
1253 addToken( &root, ¤t, type, token );
1260 void Tag::addToken( Tag **root, Tag **current, Tag::TokenType type,
1261 const std::string& token )
const
1263 Tag* t =
new Tag( token );
1264 if( t->isNumber() && !t->children().size() )
1266 t->addAttribute(
TYPE, type );
1271 (*current)->addChild( t );
1277 *current = *root = t;
1281 void Tag::addOperator( Tag** root, Tag** current, Tag* arg,
1282 Tag::TokenType type,
const std::string& token )
const
1284 Tag* t =
new Tag( token );
1285 t->addAttribute(
TYPE, type );
1288 t->addAttribute(
"operator",
"true" );
1289 t->addChild( *root );
1291 *current = *root = t;
1294 bool Tag::addPredicate( Tag **root, Tag **current, Tag* token )
const
1296 if( !*root || !*current )
1299 if( ( token->isNumber() && !token->children().size() ) || token->name() ==
"+" )
1302 if( !token->hasAttribute(
"operator",
"true" ) )
1304 token->addAttribute(
TYPE, XTInteger );
1306 if( *root == *current )
1313 (*root)->removeChild( *current );
1314 (*root)->addChild( token );
1317 token->addChild( *current );
1322 token->addAttribute(
"predicate",
"true" );
1323 (*current)->addChild( token );
1329 Tag::TokenType Tag::getType(
const std::string& c )
1334 return XTOperatorLt;
1336 return XTOperatorGt;
1338 return XTOperatorMul;
1340 return XTOperatorPlus;
1342 return XTOperatorEq;
1347 bool Tag::isWhitespace(
const char c )
1349 return ( c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20 );
1352 bool Tag::isNumber()
const
1354 if( m_name.empty() )
1357 std::string::size_type l = m_name.length();
1358 std::string::size_type i = 0;
1359 while( i < l && isdigit( m_name[i] ) )
1366 ConstTagList::const_iterator it = two.begin();
1367 for( ; it != two.end(); ++it )
1368 if( std::find( one.begin(), one.end(), (*it) ) == one.end() )
1369 one.push_back( (*it) );