📄 xml.cpp
字号:
strcpy(name,p->getTag());
else
name[0]=0;
return 1;
}
TXMLElem *TXMLElem::GetSubElem(int index)
{
int i=0;
for(TXMLElem* p=child; p!=NULL; p=p->brother)
{
if(i == index)
return p;
i++;
}
return NULL;
}
TXMLElem *TXMLElem::GetSubElem(const char *tag1, const char *attrName, const char *attrValue)
{
for(TXMLElem* p=child; p!=NULL; p=p->brother)
{
if(!tag1 || stricmp(tag1, p->getTag()) == 0)
{
char* value=p->GetAttrValue(attrName);
if(value && strcmp(value,attrValue)==0)
return p;
}
}
return NULL;
}
TXMLElem *TXMLElem::GetSubElem(const char *tag1, int index)
{
int i=0;
for(TXMLElem* p=child; p!=NULL; p=p->brother)
{
if(stricmp(tag1, p->getTag()) == 0)
{
if(i == index)
return p;
i++;
}
}
return NULL;
}
int TXMLElem::deleteChild(TXMLElem* pElement)
{
TXMLElem* p=child;
if(p==NULL)
return -2;
if(p==pElement)
{
child=pElement->brother;
delete pElement;
return 0;
}
int i=1;
while(p!=NULL && p->brother!=pElement)
{
p=p->brother;
i++;
}
if(p==NULL)
return -3;
p->brother=pElement->brother;
delete pElement;
return i;
}
void TXMLElem::addChild(TXMLElem* pElement, int mode)
{
pElement->parent=this;
if(child==NULL)
{
child=pElement;
return;
}
if(mode==1)
{
TXMLElem* p=child;
while(p->brother!=NULL)
p=p->brother;
p->brother=pElement;
}
else
{
pElement->brother=child;
child=pElement;
}
}
void TXMLElem::setAttr(const char *name,const char *value)
{
if(name==NULL || value==NULL) return ;
if(attr==NULL)
{
attr=new TXMLAttr;
attr->setName(name);
attr->setValue(value);
return;
}
if(strcmp(attr->getName(),name)==0)
{
attr->setValue(value);
return;
}
TXMLAttr* p=attr;
while(1)
{
if(strcmp(p->getName(),name)==0)
{
p->setValue(value);
return;
}
if(p->brother==NULL)
{
p->brother=new TXMLAttr;
p->brother->setName(name);
p->brother->setValue(value);
return;
}
p=p->brother;
}
};
void TXMLElem::addAttr(const char *name,const char *value)
{
if(name==NULL || value==NULL) return ;
TXMLAttr* p=new TXMLAttr;
p->setName(name);
p->setValue(value);
addAttr(p);
};
// mode: 0, add elder brother; 1, add younger brother
void TXMLElem::addBrother(TXMLElem* pElement, int mode)
{
pElement->parent=parent; //if over write operator = ?
if(mode==1)
{
pElement->brother=brother;
brother=pElement;
}
else
{
TXMLElem* p=parent->child;
if(p==this)
{
pElement->brother=p;
parent->child=pElement;
}
else
{
while(p!=NULL && p->brother!=this)
p=p->brother;
pElement->brother=p->brother;
p->brother=pElement;
}
}
}
void TXMLElem::Read()
{
int bIncludeContent = ReadBeginTag();
if(bIncludeContent)
{
ReadContent();
ReadEndTag();
}
}
int TXMLElem::ReadBeginTag()
{
lineNo = lineNumber;
ASSERT_TOKEN(XML_TOKEN_START);
GetToken(); //name
ASSERT_TOKEN(XML_TOKEN_NAME);
if(strlen(tokenValue) > TAG_LENGTH)
{
XMLERROR("line %d, col %d, too long tag,the max length is %d",lineNumber, colNumber,TAG_LENGTH);
}
strcpy(m_strTag,tokenValue);
GetToken();
while(tokenType != XML_TOKEN_END && tokenType != XML_TOKEN_END2)
{
ReadAttribute();
}
int bIncludeContent = (tokenType == XML_TOKEN_END);
GetToken();
return bIncludeContent;
}
void TXMLElem::ReadAttribute()
{
ASSERT_TOKEN(XML_TOKEN_NAME);
TXMLAttr* pAttr=new TXMLAttr;
ASSERT(pAttr);
if(strlen(tokenValue) > ATTRNAME_LENGTH)
{
XMLERROR("line %d, col %d, too long attribute name,the max length is %d", lineNumber, colNumber,ATTRNAME_LENGTH);
}
pAttr->setName(tokenValue);
pAttr->lineNo = lineNumber;
addAttr(pAttr);
GetToken();
ASSERT_TOKEN(XML_TOKEN_EQUAL);
GetToken();
ASSERT_TOKEN(XML_TOKEN_STRING);
pAttr->setValue(tokenValue);
GetToken();
}
void TXMLElem::ReadEndTag()
{
ASSERT_TOKEN(XML_TOKEN_START2);
GetToken(); //name
ASSERT_TOKEN(XML_TOKEN_NAME);
if(strcmp(getTag(), tokenValue) != 0)
XMLERROR("line %d, col %d, tag %s not match %s", lineNumber, colNumber, tokenValue, getTag());
GetToken();
ASSERT_TOKEN(XML_TOKEN_END);
GetToken();
}
void TXMLElem::ReadContent()
{
char textBuf[MAX_TEXT_LEN+1];
textBuf[0] = 0;
while(tokenType != XML_TOKEN_START2)
{
if(tokenType == XML_TOKEN_TEXT)
{
if(strlen(textBuf) + strlen(textValue) > MAX_TEXT_LEN)
XMLERROR("line %d, col %d, too long text", lineNumber, colNumber);
strcat(textBuf, textValue);
GetToken();
}
else if(tokenType == XML_TOKEN_START)
{
TXMLElem* pChild = new TXMLElem();
ASSERT(pChild);
addChild(pChild);
pChild->Read();
}
else if(tokenType == XML_TOKEN_CDATA)
{
TXMLElem* pCData= new TXMLElem();
pCData->setTag("CDATA");
pCData->setContent(textValue);
addChild(pCData);
GetToken();
}
else
{
XMLERROR("line %d, col %d, invalid token", lineNumber, colNumber);
}
}
TrimAll(textBuf);
setContent(textBuf);
}
char* TXMLElem::toStr()
{
int attrNum=GetAttrNum();
int childNum=GetSubElemNum();
typedef char* PCHAR;
PCHAR* attrStr=new PCHAR[attrNum];
PCHAR* childStr=new PCHAR[childNum];
int totalLen=0;
int i=0;
TXMLAttr* pAttr=attr;
while(pAttr!=NULL)
{
attrStr[i]=pAttr->toStr();
totalLen+=strlen(attrStr[i])+1;
pAttr=pAttr->brother;
i++;
}
i=0;
TXMLElem* pChild=child;
while(pChild!=NULL)
{
childStr[i]=pChild->toStr();
totalLen+=strlen(childStr[i]);
pChild=pChild->brother;
i++;
}
totalLen+=strlen(m_strTag)*2+2+3+1+(strlen(m_strContent)*6);
char* s=new char[totalLen];
s[0]=0;
strcat(s,"<");
strcat(s,m_strTag);
for(i=0;i<attrNum;i++)
{
strcat(s," ");
strcat(s,attrStr[i]);
delete attrStr[i];
}
strcat(s,">");
if(m_strContent)
{
char* encodeResult=xmlTextEncode(m_strContent);
strcat(s,encodeResult);
delete encodeResult;
}
for(i=0;i<childNum;i++)
{
strcat(s,childStr[i]);
delete childStr[i];
}
strcat(s,"</");
strcat(s,m_strTag);
strcat(s,">");
delete attrStr;
delete childStr;
return s;
}
TXMLElem* ParseXML(char* s)
{
bReadTag = 0;
tokenType = XML_TOKEN_EOF;
tokenValue[0] = 0;
pCurrent = s;
pBuffer = s;
pLast = s;
lineNumber = 1;
colNumber = 1;
GetToken();
TXMLElem *pRoot = new TXMLElem();
ASSERT(pRoot);
try
{
pRoot->Read();
return pRoot;
}
catch(TXMLExcept e)
{
delete pRoot;
throw e;
}
}
void ASSERT_TOKEN(int x)
{
if (tokenType != x)
{
if(tokenType == XML_TOKEN_INVALID)
XMLERROR("line %d, col %d, \"%s\", Syntax Error",
lineNumber, colNumber, tokenValue);
else
XMLERROR("line %d, col %d, \"%s\" should be token type \"%s\"",
lineNumber, colNumber, tokenValue, tokenTypeStrings[x]);
}
}
void XMLERROR(const char* fmt, ...)
{
char buffer[4096];
va_list args;
va_start(args, fmt);
vsprintf(buffer, fmt, args);
va_end(args);
throw TXMLExcept(buffer);
}
void xmlTextDecode(char* xmlText)
{
char* r=xmlText;
char* w=xmlText;
while(*r!=0)
{
if(*r=='&')
{
if(strncmp(r+1,"amp;",4)==0)
{
r+=5;
*w='&';
w++;
continue;
}
if(strncmp(r+1,"lt;",3)==0)
{
r+=4;
*w='<';
w++;
continue;
}
if(strncmp(r+1,"gt;",3)==0)
{
r+=4;
*w='>';
w++;
continue;
}
if(strncmp(r+1,"apos;",5)==0)
{
r+=6;
*w='\'';
w++;
continue;
}
if(strncmp(r+1,"quot;",5)==0)
{
r+=6;
*w='"';
w++;
continue;
}
}
*w=*r;
w++;
r++;
}
*w=0;
}
char* xmlTextEncode(char* xmlText)
{
char* xmlTextResult=new char[strlen(xmlText)*6+1];
char* r=xmlText;
char* w=xmlTextResult;
while(*r!=0)
{
if(*r=='&')
{
memcpy(w,"&",5);
w+=5;
r++;
continue;
}
if(*r=='<')
{
memcpy(w,"<",4);
w+=4;
r++;
continue;
}
if(*r=='>')
{
memcpy(w,">",4);
w+=4;
r++;
continue;
}
if(*r=='\'')
{
memcpy(w,"'",6);
w+=6;
r++;
continue;
}
if(*r=='"')
{
memcpy(w,""",6);
w+=6;
r++;
continue;
}
*w=*r;
w++;
r++;
}
*w=0;
return xmlTextResult;
}
void TrimAll(char* sour)
{
char* p=sour;
if(*p==0)
return;
for(;;)
{
if(*p >0x20 || *p ==0)
break;
p++;
}
strcpy(sour,p);
if(*p ==0)
return;
p=sour+strlen(sour);
for(;;)
{
if(*p >0x20)
{
*(p+1)=0;
return;
}
p--;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -