27 const std::string& xmlns )
37 const std::string&
xmlns )
44 : m_parent( attr.m_parent ), m_name( attr.m_name ), m_value( attr.m_value ),
45 m_xmlns( attr.m_xmlns ), m_prefix( attr.m_prefix )
49 void Tag::Attribute::init(
const std::string&
name,
const std::string& value,
50 const std::string&
xmlns )
97 if( !m_xmlns.empty() )
100 if( m_parent && !m_prefix.empty() )
101 return m_parent->
xmlns( m_prefix );
108 if( !m_prefix.empty() )
112 return m_parent->
prefix( m_xmlns );
124 if( !m_prefix.empty() )
140 : m_parent( 0 ), m_children( 0 ), m_cdata( 0 ),
141 m_attribs( 0 ), m_nodes( 0 ),
150 Tag::Tag(
Tag* parent,
const std::string& name,
const std::string& cdata )
151 : m_parent( parent ), m_children( 0 ), m_cdata( 0 ),
152 m_attribs( 0 ), m_nodes( 0 ),
165 const std::string& attrib,
166 const std::string& value )
167 : m_parent( 0 ), m_children( 0 ), m_cdata( 0 ),
168 m_attribs( 0 ), m_nodes( 0 ),
169 m_name( name ), m_xmlnss( 0 )
178 const std::string& attrib,
179 const std::string& value )
180 : m_parent( parent ), m_children( 0 ), m_cdata( 0 ),
181 m_attribs( 0 ), m_nodes( 0 ),
182 m_name( name ), m_xmlnss( 0 )
194 : m_parent( 0 ), m_children( 0 ), m_cdata( 0 ), m_attribs( 0 ),
195 m_nodes( 0 ), m_xmlnss( 0 )
200 m_children = tag->m_children;
201 m_cdata = tag->m_cdata;
202 m_attribs = tag->m_attribs;
203 m_nodes = tag->m_nodes;
204 m_name = tag->m_name;
205 m_xmlns = tag->m_xmlns;
206 m_xmlnss = tag->m_xmlnss;
216 AttributeList::iterator it = m_attribs->begin();
217 while( it != m_attribs->end() )
218 (*it++)->m_parent =
this;
223 TagList::iterator it = m_children->begin();
224 while( it != m_children->end() )
225 (*it++)->m_parent =
this;
251 if( m_name != right.m_name || m_xmlns != right.m_xmlns )
254 if( m_cdata && right.m_cdata )
256 StringPList::const_iterator ct = m_cdata->begin();
257 StringPList::const_iterator ct_r = right.m_cdata->begin();
258 while( ct != m_cdata->end() && ct_r != right.m_cdata->end() && *(*ct) == *(*ct_r) )
263 if( ct != m_cdata->end() )
266 else if( m_cdata || right.m_cdata )
269 if( m_children && right.m_children )
271 TagList::const_iterator it = m_children->begin();
272 TagList::const_iterator it_r = right.m_children->begin();
273 while( it != m_children->end() && it_r != right.m_children->end() && *(*it) == *(*it_r) )
278 if( it != m_children->end() )
281 else if( m_children || right.m_children )
284 if( m_attribs && right.m_attribs )
286 AttributeList::const_iterator at = m_attribs->begin();
287 AttributeList::const_iterator at_r = right.m_attribs->begin();
288 while( at != m_attribs->end() && at_r != right.m_attribs->end() && *(*at) == *(*at_r) )
293 if( at != m_attribs->end() )
296 else if( m_attribs || right.m_attribs )
307 std::string
xml =
"<";
308 if( !m_prefix.empty() )
314 if( m_attribs && !m_attribs->empty() )
316 AttributeList::const_iterator it_a = m_attribs->begin();
317 for( ; it_a != m_attribs->end(); ++it_a )
319 xml += (*it_a)->xml();
323 if( !m_nodes || m_nodes->empty() )
328 NodeList::const_iterator it_n = m_nodes->begin();
329 for( ; it_n != m_nodes->end(); ++it_n )
331 switch( (*it_n)->type )
334 xml += (*it_n)->tag->xml();
342 if( !m_prefix.empty() )
368 AttributeList::iterator it = m_attribs->begin();
369 for( ; it != m_attribs->end(); ++it )
371 if( (*it)->name() == attr->
name()
372 && ( (*it)->xmlns() == attr->
xmlns() || (*it)->prefix() == attr->
prefix() ) )
380 m_attribs->push_back( attr );
387 if(
name.empty() || value.empty() )
419 AttributeList::iterator it = m_attribs->begin();
420 for( ; it != m_attribs->end(); ++it )
421 (*it)->m_parent =
this;
430 m_nodes =
new NodeList();
434 m_children->push_back( child );
435 child->m_parent =
this;
436 m_nodes->push_back(
new Node( child ) );
458 m_nodes =
new NodeList();
461 NodeList::iterator it = m_nodes->begin();
462 NodeList::iterator t;
463 while( it != m_nodes->end() )
465 if( (*it)->type == TypeString )
489 m_nodes =
new NodeList();
491 std::string* str =
new std::string(
cdata );
492 m_cdata->push_back( str );
493 m_nodes->push_back(
new Node( str ) );
503 StringPList::const_iterator it = m_cdata->begin();
504 for( ; it != m_cdata->end(); ++it )
513 return m_children ? *m_children : empty;
519 return m_attribs ? *m_attribs : empty;
545 return xmlns( m_prefix );
548 const std::string
Tag::xmlns(
const std::string& prefix )
const
557 StringMap::const_iterator it = m_xmlnss->find(
prefix );
558 if( it != m_xmlnss->end() )
576 if(
xmlns.empty() || !m_xmlnss )
579 StringMap::const_iterator it = m_xmlnss->begin();
580 for( ; it != m_xmlnss->end(); ++it )
582 if( (*it).second ==
xmlns )
594 AttributeList::const_iterator it = m_attribs->begin();
595 for( ; it != m_attribs->end(); ++it )
596 if( (*it)->name() ==
name )
597 return (*it)->value();
604 if(
name.empty() || !m_attribs )
607 AttributeList::const_iterator it = m_attribs->begin();
608 for( ; it != m_attribs->end(); ++it )
609 if( (*it)->name() ==
name )
610 return value.empty() || (*it)->value() == value;
616 const std::string& value )
const
629 TagList::const_iterator it = m_children->begin();
630 while( it != m_children->end() && (*it)->name() !=
name )
632 return it != m_children->end() ? (*it) : 0;
636 const std::string& value )
const
638 if( !m_children ||
name.empty() )
641 TagList::const_iterator it = m_children->begin();
642 while( it != m_children->end() && ( (*it)->name() !=
name || !(*it)->hasAttribute( attr, value ) ) )
644 return it != m_children->end() ? (*it) : 0;
649 if( !m_children ||
name.empty() ||
cdata.empty() )
652 TagList::const_iterator it = m_children->begin();
653 while( it != m_children->end() && ( (*it)->name() !=
name
654 || ( !
cdata.empty() && (*it)->cdata() !=
cdata ) ) )
656 return it != m_children->end();
661 if( !m_children || attr.empty() )
664 TagList::const_iterator it = m_children->begin();
665 while( it != m_children->end() && !(*it)->hasAttribute( attr, value ) )
667 return it != m_children->end() ? (*it) : 0;
672 Tag* t =
new Tag( m_name );
673 t->m_xmlns = m_xmlns;
674 t->m_prefix = m_prefix;
679 Tag::AttributeList::const_iterator at = m_attribs->begin();
681 for( ; at != m_attribs->end(); ++at )
685 t->m_attribs->push_back( attr );
691 t->m_xmlnss =
new StringMap( *m_xmlnss );
696 Tag::NodeList::const_iterator nt = m_nodes->begin();
697 for( ; nt != m_nodes->end(); ++nt )
699 switch( (*nt)->type )
715 const std::string& xmlns )
const
721 const std::string& xmlns )
const
724 TagList::const_iterator it = list.begin();
725 for( ; it != list.end(); ++it )
727 if( (*it)->name() ==
name && (
xmlns.empty() || (*it)->xmlns() ==
xmlns ) )
728 ret.push_back( (*it) );
735 if(
name.empty() || !m_children || !m_nodes )
739 TagList::iterator it = l.begin();
740 TagList::iterator it2;
741 while( it != l.end() )
744 NodeList::iterator itn = m_nodes->begin();
745 for( ; itn != m_nodes->end(); ++itn )
747 if( (*itn)->type == TypeTag && (*itn)->tag == (*it2) )
750 m_nodes->erase( itn );
754 m_children->remove( (*it2) );
762 m_children->remove( tag );
767 NodeList::iterator it = m_nodes->begin();
768 for( ; it != m_nodes->end(); ++it )
770 if( (*it)->type == TypeTag && (*it)->tag == tag )
773 m_nodes->erase( it );
780 const std::string& xmlns )
782 if( attr.empty() || !m_attribs )
785 AttributeList::iterator it = m_attribs->begin();
786 AttributeList::iterator it2;
787 while( it != m_attribs->end() )
790 if( (*it2)->name() == attr && ( value.empty() || (*it2)->value() == value )
791 && (
xmlns.empty() || (*it2)->xmlns() ==
xmlns ) )
794 m_attribs->erase( it2 );
802 return !l.empty() ? l.front()->cdata() :
EmptyString;
808 return !l.empty() ? l.front() : 0;
814 if( expression ==
"/" || expression ==
"//" )
817 if( m_parent && expression.length() >= 2 && expression[0] ==
'/'
818 && expression[1] !=
'/' )
822 Tag* p = parse( expression, len );
825 l = evaluateTagList( p );
839 TokenType tokenType =
static_cast<TokenType
>( atoi( token->
findAttribute(
TYPE ).c_str() ) );
843 add( result, evaluateUnion( token ) );
852 if( tokenChildren.size() )
854 bool predicatesSucceeded =
true;
855 TagList::const_iterator cit = tokenChildren.begin();
856 for( ; cit != tokenChildren.end(); ++cit )
858 if( (*cit)->hasAttribute(
"predicate",
"true" ) )
860 predicatesSucceeded = evaluatePredicate( (*cit) );
861 if( !predicatesSucceeded )
866 bool hasElementChildren =
false;
867 cit = tokenChildren.begin();
868 for( ; cit != tokenChildren.end(); ++cit )
870 if( (*cit)->hasAttribute(
"predicate",
"true" ) ||
871 (*cit)->hasAttribute(
"number",
"true" ) )
874 hasElementChildren =
true;
877 if( m_children && !m_children->empty() )
879 TagList::const_iterator it = m_children->begin();
880 for( ; it != m_children->end(); ++it )
882 add( result, (*it)->evaluateTagList( (*cit) ) );
885 else if( atoi( (*cit)->findAttribute(
TYPE ).c_str() ) == XTDoubleDot && m_parent )
887 (*cit)->addAttribute(
TYPE, XTDot );
888 add( result, m_parent->evaluateTagList( (*cit) ) );
892 if( !hasElementChildren )
893 result.push_back(
this );
898 result.push_back(
this );
912 add( result, evaluateTagList( t ) );
914 ConstTagList::const_iterator it = res2.begin();
915 for( ; it != res2.end(); ++it )
917 add( result, (*it)->evaluateTagList( t ) );
925 if( !tokenChildren.empty() )
927 add( result, evaluateTagList( tokenChildren.front() ) );
930 result.push_back(
this );
939 if( tokenChildren.size() )
941 Tag* testtoken = tokenChildren.front();
942 if( testtoken->name() ==
"*" )
944 add( result, m_parent->evaluateTagList( testtoken ) );
950 t->m_name = m_parent->m_name;
951 add( result, m_parent->evaluateTagList( t ) );
957 result.push_back( m_parent );
969 int pos = atoi( token->
name().c_str() );
971 if( pos > 0 && pos <=
static_cast<int>( res.size() ) )
973 ConstTagList::const_iterator it = res.begin();
978 result.push_back( *it );
988 bool Tag::evaluateBoolean( Tag* token )
const
994 TokenType tokenType =
static_cast<TokenType
>( atoi( token->findAttribute(
TYPE ).c_str() ) );
998 if( token->name() ==
"*" && m_attribs && m_attribs->size() )
1004 result = evaluateEquals( token );
1008 case XTOperatorLtEq:
1010 case XTOperatorGtEq:
1018 t->addAttribute(
TYPE, XTDot );
1019 t->addChild( token );
1020 result = !evaluateTagList( t ).empty();
1021 t->removeChild( token );
1032 bool Tag::evaluateEquals( Tag* token )
const
1034 if( !token || token->children().size() != 2 )
1037 bool result =
false;
1038 TagList::const_iterator it = token->children().begin();
1042 TokenType tt1 =
static_cast<TokenType
>( atoi( ch1->findAttribute(
TYPE ).c_str() ) );
1043 TokenType tt2 =
static_cast<TokenType
>( atoi( ch2->findAttribute(
TYPE ).c_str() ) );
1070 result = ( ch1->name() == ch2->name() );
1090 TagList::const_iterator it = m_children->begin();
1091 for( ; it != m_children->end(); ++it )
1093 result.push_back( (*it) );
1094 add( result, (*it)->allDescendants() );
1105 const TagList& l = token->children();
1106 TagList::const_iterator it = l.begin();
1107 for( ; it != l.end(); ++it )
1109 add( result, evaluateTagList( (*it) ) );
1114 void Tag::closePreviousToken( Tag** root, Tag** current, Tag::TokenType& type, std::string& tok )
const
1118 addToken( root, current, type, tok );
1124 Tag* Tag::parse(
const std::string& expression,
unsigned& len, Tag::TokenType border )
const
1127 Tag* current = root;
1136 Tag::TokenType type = XTElement;
1139 for( ; len < expression.length(); ++len )
1141 c = expression[len];
1142 if( type == XTLiteralInside && c !=
'\'' )
1151 closePreviousToken( &root, ¤t, type, token );
1153 if( len < expression.length()-1 && expression[len+1] ==
'/' )
1156 type = XTDoubleSlash;
1166 closePreviousToken( &root, ¤t, type, token );
1170 closePreviousToken( &root, ¤t, type, token );
1171 Tag* t = parse( expression, ++len, XTRightBracket );
1172 if( !addPredicate( &root, ¤t, t ) )
1178 closePreviousToken( &root, ¤t, type, token );
1179 Tag* t = parse( expression, ++len, XTRightParenthesis );
1183 t->addAttribute(
"argument",
"true" );
1184 current->addChild( t );
1194 closePreviousToken( &root, ¤t, type, token );
1198 if( type == XTLiteralInside )
1199 if( expression[len - 2] ==
'\\' )
1200 token[token.length() - 2] = c;
1204 type = XTLiteralInside;
1211 if( token.size() == 1 )
1213 if( len < expression.length()-1 && expression[len+1] ==
'.' )
1232 addToken( &root, ¤t, type,
"*" );
1241 closePreviousToken( &root, ¤t, type, token );
1242 std::string s( 1, c );
1243 Tag::TokenType ttype = getType( s );
1244 if( ttype <= border )
1246 Tag* t = parse( expression, ++len, ttype );
1247 addOperator( &root, ¤t, t, ttype, s );
1248 if( border == XTRightBracket )
1257 if( !token.empty() )
1258 addToken( &root, ¤t, type, token );
1265 void Tag::addToken( Tag **root, Tag **current, Tag::TokenType type,
1266 const std::string& token )
const
1268 Tag* t =
new Tag( token );
1269 if( t->isNumber() && !t->children().size() )
1271 t->addAttribute(
TYPE, type );
1276 (*current)->addChild( t );
1282 *current = *root = t;
1286 void Tag::addOperator( Tag** root, Tag** current, Tag* arg,
1287 Tag::TokenType type,
const std::string& token )
const
1289 Tag* t =
new Tag( token );
1290 t->addAttribute(
TYPE, type );
1293 t->addAttribute(
"operator",
"true" );
1294 t->addChild( *root );
1296 *current = *root = t;
1299 bool Tag::addPredicate( Tag **root, Tag **current, Tag* token )
const
1301 if( !*root || !*current )
1304 if( ( token->isNumber() && !token->children().size() ) || token->name() ==
"+" )
1307 if( !token->hasAttribute(
"operator",
"true" ) )
1309 token->addAttribute(
TYPE, XTInteger );
1311 if( *root == *current )
1318 (*root)->removeChild( *current );
1319 (*root)->addChild( token );
1322 token->addChild( *current );
1327 token->addAttribute(
"predicate",
"true" );
1328 (*current)->addChild( token );
1334 Tag::TokenType Tag::getType(
const std::string& c )
1339 return XTOperatorLt;
1341 return XTOperatorGt;
1343 return XTOperatorMul;
1345 return XTOperatorPlus;
1347 return XTOperatorEq;
1352 bool Tag::isWhitespace(
const char c )
1354 return ( c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20 );
1357 bool Tag::isNumber()
const
1359 if( m_name.empty() )
1362 std::string::size_type l = m_name.length();
1363 std::string::size_type i = 0;
1364 while( i < l && isdigit( m_name[i] ) )
1371 ConstTagList::const_iterator it = two.begin();
1372 for( ; it != two.end(); ++it )
1373 if( std::find( one.begin(), one.end(), (*it) ) == one.end() )
1374 one.push_back( (*it) );
bool setPrefix(const std::string &prefix)
const std::string xmlns() const
const std::string & value() const
bool setValue(const std::string &value)
const std::string & name() const
const std::string xml() const
const std::string & prefix() const
bool setXmlns(const std::string &xmlns)
Attribute(Tag *parent, const std::string &name, const std::string &value, const std::string &xmlns=EmptyString)
This is an abstraction of an XML element.
Tag * findChildWithAttrib(const std::string &attr, const std::string &value=EmptyString) const
Tag * findChild(const std::string &name) const
bool hasChildWithCData(const std::string &name, const std::string &cdata) const
bool setPrefix(const std::string &prefix)
bool setCData(const std::string &cdata)
const Tag * findTag(const std::string &expression) const
void removeChild(const std::string &name, const std::string &xmlns=EmptyString)
const std::string & prefix() const
const std::string xmlns() const
void removeAttribute(const std::string &attr, const std::string &value=EmptyString, const std::string &xmlns=EmptyString)
void addChildCopy(const Tag *child)
bool addAttribute(Attribute *attr)
bool hasChild(const std::string &name, const std::string &attr=EmptyString, const std::string &value=EmptyString) const
std::list< Attribute * > AttributeList
ConstTagList findTagList(const std::string &expression) const
void addChild(Tag *child)
const std::string findCData(const std::string &expression) const
bool hasAttribute(const std::string &name, const std::string &value=EmptyString) const
bool operator==(const Tag &right) const
const AttributeList & attributes() const
const std::string cdata() const
const std::string & findAttribute(const std::string &name) const
TagList findChildren(const std::string &name, const std::string &xmlns=EmptyString) const
bool addCData(const std::string &cdata)
const std::string & name() const
Tag(const std::string &name, const std::string &cdata=EmptyString)
const std::string xml() const
const TagList & children() const
void setAttributes(const AttributeList &attributes)
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
void appendEscaped(std::string &target, const std::string &data)
bool checkValidXMLChars(const std::string &data)
void clearList(std::list< T * > &L)
The namespace for the gloox library.
std::list< Tag * > TagList
std::list< std::string * > StringPList
const std::string EmptyString
std::list< const Tag * > ConstTagList
std::map< std::string, std::string > StringMap