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

📄 xmlparser.cpp

📁 upnpForWindows by microsoft
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                            }                        }                    }                    break;                // If we found an end tag                case eTokenTagEnd:                    // If we have node text then add this to the element                    if (lpszText)                    {                        cbTemp = (int)(token.pStr - lpszText);                        FindEndOfText(lpszText, &cbTemp);                        addText(fromXMLString(lpszText,cbTemp));                        lpszText = NULL;                    }                    // Find the name of the end tag                    token = GetNextToken(pXML, &cbTemp, &type);                    // The end tag should be text                    if (type != eTokenText)                    {                        pXML->error = eXMLErrorMissingEndTagName;                        return FALSE;                    }                    lpszTemp = token.pStr;                    // After the end tag we should find a closing tag                    token = GetNextToken(pXML, &cbToken, &type);                    if (type != eTokenCloseTag)                    {                        pXML->error = eXMLErrorMissingEndTagName;                        return FALSE;                    }                    // We need to return to the previous caller.  If the name                    // of the tag cannot be found we need to keep returning to                    // caller until we find a match                    if (myTagCompare(d->lpszName, lpszTemp) != 0)#ifdef STRICT_PARSING                    {                        pXML->error=eXMLErrorUnmatchedEndTag;                        return FALSE;                    }#else                    {                        pXML->error=eXMLErrorMissingEndTag;                        pXML->lpEndTag = lpszTemp;                        pXML->cbEndTag = cbTemp;                    }#endif                    // Return to the caller                    exactMemory(d);                    return TRUE;                // If we found a clear (unformatted) token                case eTokenClear:                    // If we have node text then add this to the element                    if (lpszText)                    {                        cbTemp = (int)(token.pStr - lpszText);                        FindEndOfText(lpszText, &cbTemp);                        addText(stringDup(lpszText,cbTemp));                        lpszText = NULL;                    }                    if (!ParseClearTag(pXML, token.pClr))                    {                        return FALSE;                    }                    break;                // Errors...                case eTokenCloseTag:          /* '>'         */                case eTokenShortHandClose:    /* '/>'        */                    pXML->error = eXMLErrorUnexpectedToken;                    return FALSE;                default:                    break;                }                break;            // If we are inside a tag definition we need to search for attributes            case eInsideTag:                // Check what part of the attribute (name, equals, value) we                // are looking for.                switch(attrib)                {                // If we are looking for a new attribute                case eAttribName:                    // Check what the current token type is                    switch(type)                    {                    // 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;                        break;                    // If we found a short hand '/>' closing tag then we can                    // return to the caller                    case eTokenShortHandClose:                        exactMemory(d);                        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(type)                    {                    // If the current type is text...                    // Eg.  'Attribute AnotherAttribute'                    case eTokenText:                        // Add the unvalued attribute to the list                        addAttribute(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                        if (d->isDeclaration &&                            (lpszTemp[cbTemp-1]) == _T('?'))                        {                            cbTemp--;                        }                        if (cbTemp)                        {                            // Add the unvalued attribute to the list                            addAttribute(stringDup(lpszTemp,cbTemp), NULL);                        }                        // If this is the end of the tag then return to the caller                        if (type == 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(type)                    {                    // 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]) == _T('?'))                        {                            cbToken--;                        }                        if (cbTemp)                        {                            // Add the valued attribute to the list                            if (type==eTokenQuotedText)                                { token.pStr++; cbToken-=2; }                            addAttribute(stringDup(lpszTemp,cbTemp),fromXMLString(token.pStr,cbToken));                        }                        // 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        {            return FALSE;        }    }}// Count the number of lines and columns in an XML string.static void CountLinesAndColumns(LPCTSTR lpXML, int nUpto, XMLResults *pResults){    TCHAR ch;    int n;    assert(lpXML);    assert(pResults);    pResults->nLine = 1;    pResults->nColumn = 1;    for(n=0; n<nUpto; n++)    {        ch = lpXML[n];        assert(ch);        if (ch == _T('\n'))        {            pResults->nLine++;            pResults->nColumn = 1;        }        else pResults->nColumn++;    }}// Parse XML and return the root element.XMLNode XMLNode::parseString(LPCTSTR lpszXML, LPCTSTR tag, XMLResults *pResults){    if (!lpszXML)    {        if (pResults)        {            pResults->error=eXMLErrorNoElements;            pResults->nLine=0;            pResults->nColumn=0;        }        return emptyXMLNode;    }    static struct ClearTag tags[] =    {        {    _T("<![CDATA["),    _T("]]>")       },        {    _T("<PRE>"),        _T("</PRE>")    },        {    _T("<Script>"),     _T("</Script>") },        {    _T("<!--"),         _T("-->")       },        {    _T("<!DOCTYPE"),    _T(">")         },        {    NULL,               NULL            }    };    enum XMLError error;    XMLNode xnode(NULL,NULL,FALSE);    struct XML xml={ NULL, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE , NULL};    xml.lpXML = lpszXML;    xml.pClrTags = tags;    // Create header element    xnode.ParseXMLElement(&xml);    error = xml.error;    // If an error occurred    if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag))    {        if (tag&&_tcslen(tag))        {            XMLNode nodeTmp;            int i=0;            while (i<xnode.nChildNode())            {                nodeTmp=xnode.getChildNode(i);                if (_tcsicmp(nodeTmp.getName(),tag)==0) break;                if (nodeTmp.isDeclaration()) { xnode=nodeTmp; i=0; } else i++;            }            if (i<0)            {                if (pResults)                {                    pResults->error=eXMLErrorTagNotFound;                    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)&&(error!=eXMLErrorMissingEndTag))        {            // Find which line and column it starts on.            CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults);        }    }    return xnode;}XMLNode XMLNode::parseFile(const char *filename, LPCTSTR tag, XMLResults *pResults){    FILE *f=fopen(filename,"rb");    if (f==NULL)    {        if (pResults)        {            pResults->error=eXMLErrorFileNotFound;            pResults->nLine=0;            pResults->nColumn=0;        }        return emptyXMLNode;    }    fseek(f,0,SEEK_END);    int l=ftell(f);    fseek(f,0,SEEK_SET);    char *buf=(char*)malloc(l+1);    fread(buf,l,1,f);    fclose(f);    buf[l]=0;#ifdef WIN32#ifdef _UNICODE    if (!IsTextUnicode(buf,mmin(l,10000),NULL))    {        LPTSTR b2=(LPTSTR)malloc(l*2+2);        MultiByteToWideChar(CP_ACP,          // code page                            MB_PRECOMPOSED,  // character-type options                            buf,             // string to map                            l,               // number of bytes in string                            b2,              // wide-character buffer                            l*2+2);          // size of buffer        free(buf);        buf=(char*)b2;    }#else    if (IsTextUnicode(buf,mmin(l,10000),NULL))    {        l>>=1;        LPTSTR b2=(LPTSTR)malloc(l+2);        WideCharToMultiByte(CP_ACP,                      // code page                            0,                           // performance and mapping flags                            (const WCHAR*)buf,           // wide-character string                            l,                           // number of chars in string                            b2,                          // buffer for new string                            l+2,                         // size of buffer                            NULL,                        // default for unmappable chars                            NULL                         // set when default char used                           );        free(buf);        buf=(char*)b2;    }#endif#endif    XMLNode x=parseString((LPTSTR)buf,tag,pResults);    free(buf);    return x;}XMLNode XMLNode::openFileHelper(const char *lpszXML, LPCTSTR tag){    XMLResults pResults;    XMLNode xnode=XMLNode::parseFile(lpszXML, tag, &pResults);    if (pResults.error != eXMLErrorNone)    {        printf(            "XML Parsing error inside file '%s'.\n"#ifdef _UNICODE            "Error: %S\n"#else            "Error: %s\n"#endif            "At line %i, column %i.\n",lpszXML,            XMLNode::getError(pResults.error),pResults.nLine,pResults.nColumn);        if (pResults.error==eXMLErrorTagNotFound)        {#ifdef _UNICODE            printf("Tag is '%S'.\n",tag);#else            printf("Tag is '%s'.\n",tag);#endif        }        exit(255);    }    return xnode;}XMLNodeContents XMLNode::enumContents(int i){    XMLNodeContents c;    if (!d) { c.type=eNodeNULL; return c; }    c.type=(XMLElementType)(d->pOrder[i]&3);    i=(d->pOrder[i])>>2;    switch (c.type)    {        case eNodeChild:     c.child = d->pChild[i];      break;        case eNodeAttribute: c.attrib= d->pAttribute[i];  break;        case eNodeText:      c.text  = d->pText[i];       break;        case eNodeClear:     c.clear = d->pClear[i];      break;        default: break;    }    return c;}// private:void *XMLNode::enumContent(XMLNodeData *pEntry, int i, XMLElementType *nodeType){    XMLElementType j=(XMLElementType)(pEntry->pOrder[i]&3);    *nodeType=j;    i=(pEntry->pOrder[i])>>2;    switch (j)

⌨️ 快捷键说明

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