更新下自己的xml操作类,加入了release函数,在delete时调用,释放节点,在程序中可以有效防止内存泄露。
xml.h
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);
}
本文有不足之处,还望大家多多指正