更新下自己的xml操作类,加入了release函数,在delete时调用,释放节点,在程序中可以有效防止内存泄露。
xml.h
};
class nodecollect{
public:
nodecollect();
int getcount();
node *item(int);
void push(node*);
private:
int count;
vector<node*> v;
};
class xml{
public:
xml();
~xml();
void loadstring(string);
void scan(string);
void out(string&,node *);
node *getchild(int);
nodecollect *getnodebyname(string);
int getcount();
node *createnode(string);
node *createtextnode(string);
void loadfile(string);
void savefile(string,int =ansi);
void flush();
string gettext();
node *insertpi();
xml* append(node *);
nodecollect *selectnodes(string);
nodecollect *select(string,nodecollect * =0,node * =0);
void loadurl(string);
wstring UTF8ToUnicode( const string& );
string UnicodeToANSI( const wstring& ) ;
enum {ansi=1,unicode=2,utf8=3};
void release(node *);
private:
friend class node;
node* root;
int count;
string text;
void output(node *,string&);
};
xml.cpp
#include "xml.h" xml::xml(){ root=0; count=0; } xml::~xml(){ release(root); root=0; } void xml::release(node *n){ node *n1=n; if(!n1){ return; } while(1){ if(n1->child){ release(n1->child); }else{ if(n1->next){ release(n1->next); }else{ if(n1->getprevious()){ n1->getprevious()->next=0; }else{ if(n1->parent) n1->parent->child=0; } delete n1; return; } } } } wstring xml::UTF8ToUnicode( const string& str ) { int len = str.length(); int unicodeLen = ::MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, NULL, 0 ); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen ); wstring rt = ( wchar_t* )pUnicode; delete pUnicode; return rt; } string xml::UnicodeToANSI( const wstring& str ) { char* pElementText; int iTextLen; // wide char to multi char iTextLen = WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL ); pElementText = new char[iTextLen + 1]; memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) ); WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL ); string strText = pElementText; delete[] pElementText; return strText; } void xml::loadstring(string s){ scan(s); } void xml::loadurl(string s){ HINTERNET ie=InternetOpenA("sx",INTERNET_OPEN_TYPE_PRECONFIG,0,0,0); HINTERNET ieo=InternetOpenUrlA(ie,s.data(),0,0,INTERNET_FLAG_RELOAD,0); DWORD read=0; char b[100]={0}; InternetReadFile(ieo,b,98,&read); if(b[0]=='\xff' && b[1]=='\xfe'){ wstring s1; s1=(wchar_t*)(b+2); while(1){ memset(b,0,100); InternetReadFile(ieo,b,98,&read); if(read==0){ break; } s1+=(wchar_t*)b; } text=UnicodeToANSI(s1); }else if(b[0]=='\xef' && b[1]=='\xbb' && b[2]=='\xbf'){ text=(b+3); while(1){ memset(b,0,100); InternetReadFile(ieo,b,99,&read); if(read==0){ break; } text+=b; } text=UnicodeToANSI(UTF8ToUnicode(text)); }else{ text=b; while(1){ memset(b,0,100); InternetReadFile(ieo,b,99,&read); if(read==0){ break; } text+=b; } } loadstring(text); InternetCloseHandle(ieo); InternetCloseHandle(ie); } void xml::scan(string s){ int i=0; node *p=0; while(1){ if(i==s.length()){ break; } if(s[i]=='<' && s[i+1]!='/'){ node *n=new node; count++; n->next=0; n->child=0; n->count=0; n->x=this; n->type="node"; if(s[i+1]=='!'){ n->type="cdata"; } if(p){ n->parent=p; n->parent->count++; node *n1=p->child; if(n1){ while(n1->next){ n1=n1->next; } n1->next=n; }else{ p->child=n; } }else{ n->parent=0; if(!root){ root=n; }else{ node* n1=root; while(n1->next){ n1=n1->next; } n1->next=n; } } i++; while(s[i]!='>'){ if(s[i]!='/') n->data.append(1,s[i]); i++; } int index=n->data.find(' '); n->tag=n->data.substr(0,index!=-1?index:n->data.find('>')); if(s[i-1]!='/' && s[i-1]!='?' && s[i-1]!=']'){ p=n; } }else if(s[i]=='<' && s[i+1]=='/'){ if(p->parent){ p=p->parent; }else{ p=0; } while(s[i]!='>'){ char t=s[i]; i++; } }else if(s[i]!='\t' && s[i]!=' ' && s[i]!='\r' && s[i]!='\n'){ node *n=new node; count++; n->next=0; n->child=0; n->count=0; n->parent=p; n->x=this; n->type="text"; n->parent->count++; node *n1=p->child; if(n1){ while(n1->next){ n1=n1->next; } n1->next=n; }else{ p->child=n; } while(s[i]!='<'){ n->data.append(1,s[i]); i++; } for(int i1=n->data.length()-1;i1>=0;i1--){ if(n->data[i1]!='\t' && n->data[i1]!=' ' && n->data[i1]!='\r' && n->data[i1]!='\n'){ break; }else{ n->data.erase(i1,1); } } continue; } i++; } } void xml::out(string& s,node *n=0){ if(!n){ node *r=root; while(r){ output(r,s); s+="\r\n"; r=r->next; } } else{ output(n,s); } } void xml::output(node * n,string& s){ node *n1=n; int tab=0; if(n1->gettype()=="text"){ s=s+n1->data; return; }else if(n1->child){ s=s+"<"+n1->data+">"+"\r\n"; }else if(n1->gettag()=="?xml"){ s=s+"<"+n1->data+">"; return; }else{ s=s+"<"+n1->data+"/>"; return; } while(1){ if(n1->child){ n1=n1->child; tab++; for(int i1=0;i1<tab;i1++){ s=s+"\t"; } if(n1->type=="text"){ s=s+n1->data+"\r\n"; }else if(n1->gettype()=="cdata"){ s=s+"<"+n1->data+">\r\n"; }else{ if(n1->count>0){ s=s+"<"+n1->data+">"+"\r\n"; }else{ s=s+"<"+n1->data+"/>"+"\r\n"; } } }else if(n1->next && n1!=n){ if(n1->count>0){ for(int i2=0;i2<tab;i2++){ s=s+"\t"; } s=s+"</"+n1->tag+">"+"\r\n"; } n1=n1->next; for(int i1=0;i1<tab;i1++){ s=s+"\t"; } if(n1->type=="text"){ s=s+n1->data+"\r\n"; }else if(n1->gettype()=="cdata"){ s=s+"<"+n1->data+">\r\n"; }else{ if(n1->count>0){ s=s+"<"+n1->data+">"+"\r\n"; }else{ s=s+"<"+n1->data+"/>"+"\r\n"; } } }else{ //s=s+"</"+n1->tag+">"+"/r/n"; node *n2=n1->parent,*n3=0; if(n2 && n2!=n){ while(n2->next==0){ tab--; for(int i1=0;i1<tab;i1++){ s=s+"\t"; } s=s+"</"+n2->tag+">"+"\r\n"; n3=n2; n2=n2->parent; if(n2==n){ tab--; for(int i1=0;i1<tab;i1++){ s=s+"\t"; } s=s+"</"+n->tag+">"; goto a; } } tab--; for(int i1=0;i1<tab;i1++){ s=s+"\t"; } s=s+"</"+n2->tag+">"+"\r\n"; n1=n2->next; for(int i2=0;i2<tab;i2++){ s=s+"\t"; } if(n1->count>0){ s=s+"<"+n1->data+">"+"\r\n"; }else{ s=s+"<"+n1->data+"/>"+"\r\n"; } }else{ s=s+"</"+n->tag+">"; a: break; } } } } nodecollect *xml::selectnodes(string s){ nodecollect *nc=new nodecollect; int i=0; if(s[i]=='/' && s[i+1]=='/'){ int index=s.find('/',i+2); string s1; if(index!=-1){ s1=s.substr(2,index-2); }else{ s1=s.substr(2); } int i1=0; while(getchild(i1)){ node *n=getchild(i1); if(n->gettag()==s1){ if(index==-1){ nc->push(n); }else if(s[index+1]=='/'){ string s2=s.substr(index+2); for(int i2=0;i2<n->gettotlecount();i2++){ if(n->getchild(i2)->gettag()==s2){ nc->push(n->getchild(i2)); } } }else{ node *n1=n->child; string s2=s.substr(index+1); while(n1){ if(n1->gettag()==s2){ nc->push(n1); } n1=n1->next; } } } i1++; } }else{ int index=s.find('/',i+1); string s1; if(index!=-1){ s1=s.substr(1,index-1); }else{ s1=s.substr(1); } node *nn=root; while(nn){ node *n=nn; if(n->gettag()==s1){ if(index==-1){ nc->push(n); }else if(s[index+1]=='/'){ string s2=s.substr(index+2); for(int i2=0;i2<n->gettotlecount();i2++){ if(n->getchild(i2)->gettag()==s2){ nc->push(n->getchild(i2)); } } }else{ node *n1=n->child; string s2=s.substr(index+1); while(n1){ if(n1->gettag()==s2){ nc->push(n1); } n1=n1->next; } } } nn=nn->next; } } return nc; } nodecollect *xml::select(string s,nodecollect *nc,node *n){ if(!nc){ nc=new nodecollect; } if(s[1]=='/'){ int index=s.find('/',2); if(index==-1){ string data=s.substr(2); int attr=data.find('['); if(attr!=-1){ string tag,k,v; tag=data.substr(0,attr); int i1=attr+1; while(data[i1]!='='){ k.append(1,data[i1]); i1++; } i1++; while(data[i1]!=']'){ v.append(1,data[i1]); i1++; } if(n){ int l=n->gettotlecount(); for(int i2=0;i2<l;i2++){ node *n1=n->getchild(i2); if(n1->gettag()==tag && n1->getattr(k)==v){ nc->push(n1); } } return nc; }else{ n=root; while(n){ if(n->gettag()==tag && n->getattr(k)==v){ nc->push(n); } select(s,nc,n); n=n->next; } return nc; } }else{ string tag=data; if(n){ int l=n->gettotlecount(); for(int i2=0;i2<l;i2++){ node *n1=n->getchild(i2); if(n1->gettag()==tag){ nc->push(n1); } } return nc; }else{ n=root; while(n){ if(n->gettag()==tag){ nc->push(n); } select(s,nc,n); n=n->next; } return nc; } } }else{ string data=s.substr(2,index-2); string next=s.substr(index); int attr=data.find('['); if(attr!=-1){ string tag,k,v; tag=data.substr(0,attr); int i1=attr+1; while(data[i1]!='='){ k.append(1,data[i1]); i1++; } i1++; while(data[i1]!=']'){ v.append(1,data[i1]); i1++; } if(n){ int l=n->gettotlecount(); for(int i2=0;i2<l;i2++){ node *n1=n->getchild(i2); if(n1->gettag()==tag && n1->getattr(k)==v){ select(next,nc,n1); } } return nc; }else{ n=root; while(n){ if(n->gettag()==tag && n->getattr(k)==v){ select(next,nc,n); } for(int i=0;i<n->gettotlecount();i++){ if(n->getchild(i)->gettag()==tag && n->getchild(i)->getattr(k)==v){ select(next,nc,n->getchild(i)); } } n=n->next; } } }else{ string tag=data; if(n){ int l=n->gettotlecount(); for(int i2=0;i2<l;i2++){ node *n1=n->getchild(i2); if(n1->gettag()==tag){ select(next,nc,n1); } } return nc; }else{ n=root; while(n){ if(n->gettag()==tag){ select(next,nc,n); } for(int i=0;i<n->gettotlecount();i++){ if(n->getchild(i)->gettag()==tag){ select(next,nc,n->getchild(i)); } } n=n->next; } } } } }else{ int index=s.find('/',1); if(index==-1){ string data=s.substr(1); int attr=data.find('['); if(attr!=-1){ string tag,k,v; tag=data.substr(0,attr); int i1=attr+1; while(data[i1]!='='){ k.append(1,data[i1]); i1++; } i1++; while(data[i1]!=']'){ v.append(1,data[i1]); i1++; } if(n){ node *n1=n->child; while(n1){ if(n1->gettag()==tag && n1->getattr(k)==v){ nc->push(n1); } n1=n1->next; } return nc; }else{ n=root; while(n){ if(n->gettag()==tag && n->getattr(k)==v){ nc->push(n); } n=n->next; } return nc; } }else{ string tag=data; if(n){ node *n1=n->child; while(n1){ if(n1->gettag()==tag){ nc->push(n1); } n1=n1->next; } return nc; }else{ n=root; while(n){ if(n->gettag()==tag){ nc->push(n); } n=n->next; } return nc; } } }else{ string data=s.substr(1,index-1); string next=s.substr(index); int attr=data.find('['); if(attr!=-1){ string tag,k,v; tag=data.substr(0,attr); int i1=attr+1; while(data[i1]!='='){ k.append(1,data[i1]); i1++; } i1++; while(data[i1]!=']'){ v.append(1,data[i1]); i1++; } if(n){ node *n1=n->child; while(n1){ if(n1->gettag()==tag && n1->getattr(k)==v){ select(next,nc,n1); } n1=n1->next; } return nc; }else{ n=root; while(n){ if(n->gettag()==tag && n->getattr(k)==v){ select(next,nc,n); } n=n->next; } } }else{ string tag=data; if(n){ node *n1=n->child; while(n1){ if(n1->gettag()==tag){ select(next,nc,n1); } n1=n1->next; } return nc; }else{ n=root; while(n){ if(n->gettag()==tag){ select(next,nc,n); } n=n->next; } } } } } return nc; } int xml::getcount(){ return count; } node *xml::getchild(int i){ int i1=0; node *n=root; while(i1!=i){ if(!n){ return 0; } if(n->child){ n=n->child; }else{ if(n->next){ n=n->next; }else{ while(n->parent && n->parent->next==0){ n=n->parent; } if(n->parent){ n=n->parent->next; }else{ return 0; } } } i1++; } return n; } nodecollect *xml::getnodebyname(string s){ node *n1=root; nodecollect *nc=new nodecollect; if(n1->tag==s){ nc->push(n1); } while(1){ if(n1->child){ n1=n1->child; if(n1->tag==s){ nc->push(n1); } }else if(n1->next){ n1=n1->next; if(n1->tag==s){ nc->push(n1); } }else{ //cout<<"</"<<n1->tag<<">"<<endl; node *n2=n1->parent,*n3=0; if(n2){ while(n2->next==0){ n3=n2; n2=n2->parent; if(n2==0){ goto a; } } n1=n2->next; if(n1->tag==s){ nc->push(n1); } }else{ // cout<<"</"<<n1->tag<<">"<<endl; a: break; } } } return nc; } node *xml::createnode(string s){ node *n=new node; n->x=this; n->child=0; n->count=0; n->next=0; n->parent=0; n->type="node"; n->tag=s; n->data=s; return n; } node *xml::createtextnode(string s){ node *n=new node; n->x=this; n->child=0; n->count=0; n->next=0; n->parent=0; n->type="text"; n->data=s; return n; } void xml::loadfile(string s){ if(root) { release(root); root=0; } text.clear(); FILE *f=fopen(s.data(),"rb"); char buf[2048]={0}; fread(buf,1,2040,f); if(buf[0]=='\xff' && buf[1]=='\xfe'){ wstring s1; s1=(wchar_t*)(buf+2); while(!feof(f)){ memset(buf,0,2048); fread(buf,1,2046,f); s1=s1+(wchar_t*)buf; } text=UnicodeToANSI(s1); }else if(buf[0]=='\xef' && buf[1]=='\xbb' && buf[2]=='\xbf'){ text=(buf+3); while(!feof(f)){ memset(buf,0,2048); fread(buf,1,2047,f); text=text+buf; } text=UnicodeToANSI(UTF8ToUnicode(text)); }else{ text=buf; while(!feof(f)){ memset(buf,0,2048); fread(buf,1,2047,f); text+=buf; } } fclose(f); loadstring(text); } void xml::savefile(string s,int mode){ flush(); FILE *f=fopen(s.data(),"wb"); if(mode==ansi){ fwrite(text.data(),1,text.length(),f); }else if(mode==unicode){ fwrite("\xff\xfe",1,2,f); int wcsLen = ::MultiByteToWideChar(CP_ACP, NULL, text.data(), text.length(), NULL, 0); //分配空间要给'/0'留个空间,MultiByteToWideChar不会给'/0'空间 wchar_t* wszString = new wchar_t[wcsLen + 1]; //转换 ::MultiByteToWideChar(CP_ACP, NULL, text.data(), text.length(), wszString, wcsLen); //最后加上'/0' wszString[wcsLen] = '\0'; fwrite(wszString,2,wcsLen,f); delete []wszString; }else if(mode==utf8){ fwrite("\xef\xbb\xbf",1,3,f); int wcsLen = ::MultiByteToWideChar(CP_ACP, NULL, text.data(), text.length(), NULL, 0); //分配空间要给'/0'留个空间,MultiByteToWideChar不会给'/0'空间 wchar_t* wszString = new wchar_t[wcsLen + 1]; //转换 ::MultiByteToWideChar(CP_ACP, NULL, text.data(), text.length(), wszString, wcsLen); //最后加上'/0' wszString[wcsLen] = '\0'; int Len = ::WideCharToMultiByte( CP_UTF8, 0, wszString, -1, NULL, 0 ,0,0); char * p; p = new char[Len+1]; memset(p,0,(Len+1)*sizeof(char)); WideCharToMultiByte( CP_UTF8, 0, wszString, -1, p, Len,0,0); string s2 =p; delete p; fwrite(s2.data(),1,s2.length(),f); delete []wszString; } fclose(f); } void xml::flush(){ text=""; string s; node *r=root; while(r){ output(r,s); text+=s; s=""; text+="\r\n"; r=r->next; } //scan(text); } string xml::gettext(){ return text; } node *xml::insertpi(){ node * n=createnode("?xml"); n->setattr("version","1.0"); n->data+="?"; n->next=root; root=n; count++; return n; } xml* xml::append(node *n){ if(root){ node *n1=root; while(n1->next){ n1=n1->next; } n1->next=n; }else{ root=n; } count+=n->gettotlecount()+1; return this; } nodecollect::nodecollect(){ count=0; } int nodecollect::getcount(){ return count; } node *nodecollect::item(int i){ return v[i]; } void nodecollect::push(node* n){ v.push_back(n); count++; } node* node::appned(node *n){ if(child){ node *n1=child; while(n1->next){ n1=n1->next; } n1->next=n; count++; n->parent=this; x->count+=n->gettotlecount()+1; }else{ child=n; count++; n->parent=this; x->count+=n->gettotlecount()+1; } return this; } node* node::insert(int i,node *n){ if(i==0){ n->next=child; n->parent=this; count++; child=n; }else if(i==count){ appned(n); }else{ node *n1=child,*n2=0; int i1=0; while(i1!=i){ n2=n1; n1=n1->next; i1++; } n2->next=n; n->next=n1; count++; n->parent=this; } return this; } node* node::removechild(int i){ if(i==0){ node *n=child; child=child->next; count--; x->count=x->count-gettotlecount()-1; delete n; }else{ node *n=child,*n1=0; int i1=0; while(i1!=i){ n1=n; n=n->next; i1++; } n1->next=n->next; count--; x->count=x->count-gettotlecount()-1; delete n; } return this; } string node::getattr(string s){ string ss; char *i=(char*)strstr(data.data(),s.data()); c: if(i && (*(i-1)==' ' || *(i-1)=='\r' || *(i-1)=='\n' || *(i-1)=='\t') && (*(i+s.length())==' ' || *(i+s.length())=='=')){ char *i1=strstr(i+1,"\""); char *i2=strstr(i1+1,"\""); i1++; while(i1!=i2){ ss+=*i1; i1++; } }else{ if(i==0){ return ss; }else{ i=strstr(i+1,s.data()); goto c; } } return ss; } node* node::setattr(string k,string v){ char *i=(char*)strstr(data.data(),k.data()); c: if(i && (*(i-1)==' ' || *(i-1)=='\r' || *(i-1)=='\n' || *(i-1)=='\t') && (*(i+k.length())==' ' || *(i+k.length())=='=')){ char *i1=strstr(i+1,"\""); char *i2=strstr(i1+1,"\""); string d=i2; data=data.substr(0,i1-data.data()+1); data+=v; data+=d; }else{ if(i==0){ if(data.substr(data.length()-1,1)!="?"){ data=data+' '+k+"="+'\"'+v+'\"'; }else{ data=data.substr(0,data.length()-1)+' '+k+"="+'\"'+v+"\"?"; } }else{ i=strstr(i+1,k.data()); goto c; } } return this; } node* node::removeattr(string s){ char *i=(char*)strstr(data.data(),s.data()); c: if(i && (*(i-1)==' ' || *(i-1)=='\r' || *(i-1)=='\n' || *(i-1)=='\t') && (*(i+s.length())==' ' || *(i+s.length())=='=')){ char *i1=strstr(i+1,"\""); char *i2=strstr(i1+1,"\""); string d=i2+1; data=data.substr(0,i-data.data()-1); data+=d; }else{ if(i==0){ return this; }else{ i=strstr(i+1,s.data()); goto c; } } return this; } void node::remove(){ node *n=getparent(); if(n){ node *n1=getprevious(); if(n1){ n1->next=next; }else{ n->child=next; } n->count--; x->count=x->count-gettotlecount()-1; }else{ node *n1=getprevious(); if(n1){ n1->next=next; }else{ x->root=x->root->next; } x->count=x->count-gettotlecount()-1; } delete this; } node *node::getchild(int i){ int i1=-1; node *n=this; while(i1!=i){ if(n->child){ n=n->child; }else{ if(n->next){ n=n->next; }else{ while(n->parent && n->parent->next==0 && n->parent!=this){ n=n->parent; } if(n->parent!=this){ n=n->parent->next; }else{ return 0; } } } i1++; } return n; } nodecollect *node::getnodebyname(string s){ node *n1=this->child; nodecollect *nc=new nodecollect; if(n1->tag==s){ nc->push(n1); } while(1){ if(n1->child){ n1=n1->child; if(n1->tag==s){ nc->push(n1); } }else if(n1->next){ n1=n1->next; if(n1->tag==s){ nc->push(n1); } }else{ //cout<<"</"<<n1->tag<<">"<<endl; node *n2=n1->parent,*n3=0; if(n2 && n2!=this){ while(n2->next==0){ n3=n2; n2=n2->parent; if(n2==this){ goto a; } } n1=n2->next; if(n1->tag==s){ nc->push(n1); } }else{ // cout<<"</"<<n1->tag<<">"<<endl; a: break; } } } return nc; } int node::getcount(){ return count; } node *node::getnext(){ return next; } node *node::getparent(){ return parent; } node *node::getprevious(){ if(parent){ node *n=parent->child; while(n && n->next!=this){ n=n->next; } return n; }else{ node *n=x->getchild(0); while(n && n->next!=this){ n=n->next; } return n; } return 0; } string node::gettag(){ return tag; } string node::gettype(){ return type; } int node::gettotlecount(){ int i1=0; node *n=this->child; if(n) i1++; while(n){ if(n->child){ n=n->child; }else{ if(n->next){ n=n->next; }else{ while(n->parent && n->parent->next==0 && n->parent!=this){ n=n->parent; } if(n->parent!=this){ n=n->parent->next; }else{ break; } } } i1++; } return i1; } string node::gettext(){ string s; for(int i=0;i<gettotlecount();i++){ if(getchild(i)->gettype()=="text"){ s+=getchild(i)->data; } } return s; } node *node::puttext(string s){ if(child && child->gettype()=="text"){ child->remove(); } node *n=x->createtextnode(s); insert(0,n); return this; } nodecollect *node::selectnodes(string s){ nodecollect *nc=new nodecollect; int i=0; if(s[i]=='/' && s[i+1]=='/'){ int index=s.find('/',i+2); string s1; if(index!=-1){ s1=s.substr(2,index-2); }else{ s1=s.substr(2); } int i1=0; while(getchild(i1)){ node *n=getchild(i1); if(n->gettag()==s1){ if(index==-1){ nc->push(n); }else if(s[index+1]=='/'){ string s2=s.substr(index+2); for(int i2=0;i2<n->gettotlecount();i2++){ if(n->getchild(i2)->gettag()==s2){ nc->push(n->getchild(i2)); } } }else{ node *n1=n->child; string s2=s.substr(index+1); while(n1){ if(n1->gettag()==s2){ nc->push(n1); } n1=n1->next; } } } i1++; } }else{ int index=s.find('/',i+1); string s1; if(index!=-1){ s1=s.substr(1,index-1); }else{ s1=s.substr(1); } node *nn=child; while(nn){ node *n=nn; if(n->gettag()==s1){ if(index==-1){ nc->push(n); }else if(s[index+1]=='/'){ string s2=s.substr(index+2); for(int i2=0;i2<n->gettotlecount();i2++){ if(n->getchild(i2)->gettag()==s2){ nc->push(n->getchild(i2)); } } }else{ node *n1=n->child; string s2=s.substr(index+1); while(n1){ if(n1->gettag()==s2){ nc->push(n1); } n1=n1->next; } } } nn=nn->next; } } return nc; } nodecollect *node::select(string s){ return x->select(s,0,this); }
本文有不足之处,还望大家多多指正