⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlparser.cpp

📁 xml文件解析器 解析所有的xml文件 支持unicode
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                {                // If we are looking for a new attribute                case eAttribName:                    // Check what the current token type is                    switch(xtype)                    {                    // If the current type is text...                    // Eg.  'attribute'                    case eTokenText:                        // Cache the token then indicate that we are next to                        // look for the equals                        lpszTemp = token.pStr;                        cbTemp = cbToken;                        attrib = eAttribEquals;                        break;                    // If we found a closing tag...                    // Eg.  '>'                    case eTokenCloseTag:                        // We are now outside the tag                        status = eOutsideTag;                        pXML->lpszText=pXML->lpXML+pXML->nIndex;                        break;                    // If we found a short hand '/>' closing tag then we can                    // return to the caller                    case eTokenShortHandClose:                        exactMemory(d);                        pXML->lpszText=pXML->lpXML+pXML->nIndex;                        return TRUE;                    // Errors...                    case eTokenQuotedText:    /* '"SomeText"'   */                    case eTokenTagStart:      /* '<'            */                    case eTokenTagEnd:        /* '</'           */                    case eTokenEquals:        /* '='            */                    case eTokenDeclaration:   /* '<?'           */                    case eTokenClear:                        pXML->error = eXMLErrorUnexpectedToken;                        return FALSE;                    default: break;                    }                    break;                // If we are looking for an equals                case eAttribEquals:                    // Check what the current token type is                    switch(xtype)                    {                    // If the current type is text...                    // Eg.  'Attribute AnotherAttribute'                    case eTokenText:                        // Add the unvalued attribute to the list                        addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);                        // Cache the token then indicate.  We are next to                        // look for the equals attribute                        lpszTemp = token.pStr;                        cbTemp = cbToken;                        break;                    // If we found a closing tag 'Attribute >' or a short hand                    // closing tag 'Attribute />'                    case eTokenShortHandClose:                    case eTokenCloseTag:                        // If we are a declaration element '<?' then we need                        // to remove extra closing '?' if it exists                        pXML->lpszText=pXML->lpXML+pXML->nIndex;                        if (d->isDeclaration &&                            (lpszTemp[cbTemp-1]) == _X('?'))                        {                            cbTemp--;                        }                        if (cbTemp)                        {                            // Add the unvalued attribute to the list                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);                        }                        // If this is the end of the tag then return to the caller                        if (xtype == eTokenShortHandClose)                        {                            exactMemory(d);                            return TRUE;                        }                        // We are now outside the tag                        status = eOutsideTag;                        break;                    // If we found the equals token...                    // Eg.  'Attribute ='                    case eTokenEquals:                        // Indicate that we next need to search for the value                        // for the attribute                        attrib = eAttribValue;                        break;                    // Errors...                    case eTokenQuotedText:    /* 'Attribute "InvalidAttr"'*/                    case eTokenTagStart:      /* 'Attribute <'            */                    case eTokenTagEnd:        /* 'Attribute </'           */                    case eTokenDeclaration:   /* 'Attribute <?'           */                    case eTokenClear:                        pXML->error = eXMLErrorUnexpectedToken;                        return FALSE;                    default: break;                    }                    break;                // If we are looking for an attribute value                case eAttribValue:                    // Check what the current token type is                    switch(xtype)                    {                    // If the current type is text or quoted text...                    // Eg.  'Attribute = "Value"' or 'Attribute = Value' or                    // 'Attribute = 'Value''.                    case eTokenText:                    case eTokenQuotedText:                        // If we are a declaration element '<?' then we need                        // to remove extra closing '?' if it exists                        if (d->isDeclaration &&                            (token.pStr[cbToken-1]) == _X('?'))                        {                            cbToken--;                        }                        if (cbTemp)                        {                            // Add the valued attribute to the list                            if (xtype==eTokenQuotedText) { token.pStr++; cbToken-=2; }                            XMLSTR attrVal=(XMLSTR)token.pStr;                            if (attrVal)                            {                                attrVal=fromXMLString(attrVal,cbToken,pXML);                                if (!attrVal) return FALSE;                            }                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp),attrVal);                        }                        // Indicate we are searching for a new attribute                        attrib = eAttribName;                        break;                    // Errors...                    case eTokenTagStart:        /* 'Attr = <'          */                    case eTokenTagEnd:          /* 'Attr = </'         */                    case eTokenCloseTag:        /* 'Attr = >'          */                    case eTokenShortHandClose:  /* "Attr = />"         */                    case eTokenEquals:          /* 'Attr = ='          */                    case eTokenDeclaration:     /* 'Attr = <?'         */                    case eTokenClear:                        pXML->error = eXMLErrorUnexpectedToken;                        return FALSE;                        break;                    default: break;                    }                }            }        }        // If we failed to obtain the next token        else        {            if ((!d->isDeclaration)&&(d->pParent))            {#ifdef STRICT_PARSING                pXML->error=eXMLErrorUnmatchedEndTag;#else                pXML->error=eXMLErrorMissingEndTag;#endif                pXML->nIndexMissigEndTag=pXML->nIndex;            }            maybeAddTxT(pXML,pXML->lpXML+pXML->nIndex);            return FALSE;        }    }}// Count the number of lines and columns in an XML string.static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, XMLResults *pResults){    XMLCHAR ch;    assert(lpXML);    assert(pResults);    struct XML xml={ lpXML,lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };    pResults->nLine = 1;    pResults->nColumn = 1;    while (xml.nIndex<nUpto)    {        ch = getNextChar(&xml);        if (ch != _X('\n')) pResults->nColumn++;        else        {            pResults->nLine++;            pResults->nColumn=1;        }    }}// Parse XML and return the root element.XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults){    if (!lpszXML)    {        if (pResults)        {            pResults->error=eXMLErrorNoElements;            pResults->nLine=0;            pResults->nColumn=0;        }        return emptyXMLNode;    }    XMLNode xnode(NULL,NULL,FALSE);    struct XML xml={ lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };    // Create header element    xnode.ParseXMLElement(&xml);    enum XMLError error = xml.error;    if (!xnode.nChildNode()) error=eXMLErrorNoXMLTagFound;    if ((xnode.nChildNode()==1)&&(xnode.nElement()==1)) xnode=xnode.getChildNode(); // skip the empty node    // If no error occurred    if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag)||(error==eXMLErrorNoXMLTagFound))    {        XMLCSTR name=xnode.getName();        if (tag&&xstrlen(tag)&&((!name)||(xstricmp(xnode.getName(),tag))))        {            XMLNode nodeTmp;            int i=0;            while (i<xnode.nChildNode())            {                nodeTmp=xnode.getChildNode(i);                if (xstricmp(nodeTmp.getName(),tag)==0) break;                if (nodeTmp.isDeclaration()) { xnode=nodeTmp; i=0; } else i++;            }            if (i>=xnode.nChildNode())            {                if (pResults)                {                    pResults->error=eXMLErrorFirstTagNotFound;                    pResults->nLine=0;                    pResults->nColumn=0;                }                return emptyXMLNode;            }            xnode=nodeTmp;        }    } else    {        // Cleanup: this will destroy all the nodes        xnode = emptyXMLNode;    }    // If we have been given somewhere to place results    if (pResults)    {        pResults->error = error;        // If we have an error        if (error!=eXMLErrorNone)        {            if (error==eXMLErrorMissingEndTag) xml.nIndex=xml.nIndexMissigEndTag;            // Find which line and column it starts on.            CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults);        }    }    return xnode;}XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults){    if (pResults) { pResults->nLine=0; pResults->nColumn=0; }    FILE *f=xfopen(filename,_X("rb"));    if (f==NULL) { if (pResults) pResults->error=eXMLErrorFileNotFound; return emptyXMLNode; }    fseek(f,0,SEEK_END);    int l=ftell(f),headerSz=0;    if (!l) { if (pResults) pResults->error=eXMLErrorEmpty; fclose(f); return emptyXMLNode; }    fseek(f,0,SEEK_SET);    unsigned char *buf=(unsigned char*)malloc(l+4);    fread(buf,l,1,f);    fclose(f);    buf[l]=0;buf[l+1]=0;buf[l+2]=0;buf[l+3]=0;#ifdef _XMLWIDECHAR    if (guessWideCharChars)    {        if (!myIsTextWideChar(buf,l))        {            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;            XMLSTR b2=myMultiByteToWideChar((const char*)(buf+headerSz));            free(buf); buf=(unsigned char*)b2; headerSz=0;        } else        {            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;        }    }#else    if (guessWideCharChars)    {        if (myIsTextWideChar(buf,l))        {            l/=sizeof(wchar_t);            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;            char *b2=myWideCharToMultiByte((const wchar_t*)(buf+headerSz));            free(buf); buf=(unsigned char*)b2; headerSz=0;        } else        {            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;        }    }#endif    if (!buf) { if (pResults) pResults->error=eXMLErrorCharConversionError; return emptyXMLNode; }    XMLNode x=parseString((XMLSTR)(buf+headerSz),tag,pResults);    free(buf);    return x;}static inline void charmemset(XMLSTR dest,XMLCHAR c,int l) { while (l--) *(dest++)=c; }// private:// Creates an user friendly XML string from a given element with// appropriate white space and carriage returns.//// This recurses through all subnodes then adds contents of the nodes to the// string.int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat){    int nResult = 0;    int cb;    int cbElement;    int nChildFormat=-1;    int nElementI=pEntry->nChild+pEntry->nText+pEntry->nClear;    int i,j;    assert(pEntry);#define LENSTR(lpsz) (lpsz ? xstrlen(lpsz) : 0)    // If the element has no name then assume this is the head 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -