天天看點

介紹一個可用于BREW的XML解析實作

高通在BREW平台中并沒有為我們提供一個可以友善使用的API來實作XML檔案的解析,在很多情況下,我們需要操作一個XML檔案。就這事我曾電話咨詢過博路的工程師,他給出的答複是可以購買一個商業元件來實作這個功能。事實上,沒必要如此複雜,我們完全可以利用網際網路上的免費的開源代碼來實作這個功能。

本文要介紹的開源代碼就是:Martyn C Brown為我們提供的一個完全基于ANSI C實作的MCBXml。

這是一個很純的标準C實作,是以,要移植到BREW上是比較容易的。

第一步:我們直接把它揣進一個BREW工程中,編譯一下,就會發現很多的編譯錯誤出來了。(這一步的目的就是要看看它都有哪些東西不符合BREW的要求,這正是我們需要修改的地方)。

第二步:現在可以修改代碼了,簡單地利用#define将它使用的一些函數替換成BREW可以接受的形式。當然在這之前先移掉幾個頭引用,加入BREW的引用。對于頭檔案的修改就這麼簡單而已。而對于MCBXml.c的修改其它除了用#define來替換以外,還有一種方法就是“查找替換”法,呵呵,比如free換成FREE,malloc換成MALLOC之類的。

介紹一個可用于BREW的XML解析實作

#include "AEEStdLib.h"     #define _T(name)    (name)

介紹一個可用于BREW的XML解析實作

#define _tcscpy(a,b)    STRCPY(a,b)

介紹一個可用于BREW的XML解析實作

#define _tcsstr(a,b)    STRSTR(a,b)

介紹一個可用于BREW的XML解析實作

#define _tcschr(a,b)    STRCHR(a,b)

介紹一個可用于BREW的XML解析實作

#define _tcslen(a)        STRLEN(a)

介紹一個可用于BREW的XML解析實作

#define _tcsnicmp(a,b,c)  STRNICMP(a,b,c)

在MCBXml.c中,還有一個操作,我将函數McbGetError整個給注掉了(就是為了省事,如果你還要保留這個函數,額外做些工作就可以了)。

還有一個McbClearTags()函數的修改如下:

介紹一個可用于BREW的XML解析實作

McbClearTag     *  McbGetClearTags()

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

... {

介紹一個可用于BREW的XML解析實作

    struct McbClearTag * tags = (McbClearTag*)MALLOC(sizeof(McbClearTag)*6);

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

    //struct McbClearTag tags[] =

介紹一個可用于BREW的XML解析實作

    //{

介紹一個可用于BREW的XML解析實作

    //    {    _T("<![CDATA["),    _T("]]>")        },

介紹一個可用于BREW的XML解析實作

    //    {    _T("<PRE>"),        _T("</PRE>")    },

介紹一個可用于BREW的XML解析實作

    //    {    _T("<Script>"),        _T("</Script>")    },

介紹一個可用于BREW的XML解析實作

    //    {    _T("<!--"),            _T("-->")        },

介紹一個可用于BREW的XML解析實作

    //    {    _T("<!DOCTYPE"),    _T(">")            },

介紹一個可用于BREW的XML解析實作

    //    {    NULL,                NULL            }

介紹一個可用于BREW的XML解析實作

    //};

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

    MEMSET(tags,0,sizeof(McbClearTag)*6);

介紹一個可用于BREW的XML解析實作

    tags[0].lpszOpen=STRDUP("<![CDATA[");

介紹一個可用于BREW的XML解析實作

    tags[0].lpszClose=STRDUP("]]>");

介紹一個可用于BREW的XML解析實作

    tags[1].lpszOpen=STRDUP("<PRE>");

介紹一個可用于BREW的XML解析實作

    tags[1].lpszClose=STRDUP("</PRE>");

介紹一個可用于BREW的XML解析實作

    tags[2].lpszOpen=STRDUP("<!--");

介紹一個可用于BREW的XML解析實作

    tags[2].lpszClose=STRDUP("-->");

介紹一個可用于BREW的XML解析實作

    tags[3].lpszOpen=STRDUP("<!DOCTYPE");

介紹一個可用于BREW的XML解析實作

    tags[3].lpszClose=STRDUP(">");

介紹一個可用于BREW的XML解析實作

    tags[4].lpszOpen=STRDUP("<Script");

介紹一個可用于BREW的XML解析實作

    tags[4].lpszClose=STRDUP("</Script>");

介紹一個可用于BREW的XML解析實作

    tags[5].lpszOpen=NULL;

介紹一個可用于BREW的XML解析實作

    tags[5].lpszClose=NULL;

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

    return tags;

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

}

介紹一個可用于BREW的XML解析實作

在函數McbXMLElement * McbParseXML(LPCTSTR lpszXML, McbXMLResults *pResults)的實作中,最後還要注意釋放掉上面弄出來的字串:

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

  ... ...       ... {

介紹一個可用于BREW的XML解析實作

        int i;

介紹一個可用于BREW的XML解析實作

        for(i=0;i<6;i++)

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

        ...{

介紹一個可用于BREW的XML解析實作

            FREEIF(xml.pClrTags[i].lpszOpen);

介紹一個可用于BREW的XML解析實作

            FREEIF(xml.pClrTags[i].lpszClose);

介紹一個可用于BREW的XML解析實作

        }

介紹一個可用于BREW的XML解析實作

        FREEIF(xml.pClrTags);

介紹一個可用于BREW的XML解析實作

    }

介紹一個可用于BREW的XML解析實作

     return  pElement;

介紹一個可用于BREW的XML解析實作

要想編譯通過,還有一個地方要注意的,所有的assert也掉處理掉。經過上述處理,現在這兩個檔案MCBXml.h/MCBXml.c已經可以嵌入我們的BREW工程中編譯成功了。

不過,因為它預設使用的屬性值是不帶雙引号的,是以還需要做一點修改友善使用:

介紹一個可用于BREW的XML解析實作

LPTSTR McbStrdup(LPCTSTR lpszData,  int  cbData)

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

... {

介紹一個可用于BREW的XML解析實作

    //以下是新的邏輯 by YanCheng(2007-12-14)

介紹一個可用于BREW的XML解析實作

    //去掉引号

介紹一個可用于BREW的XML解析實作

    LPTSTR lpszNew;

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

    if( cbData==0 ) cbData = _tcslen(lpszData);

介紹一個可用于BREW的XML解析實作

    if( (lpszData[0]=='"' && lpszData[cbData-1]=='"') || (lpszData[0]==''' && lpszData[cbData-1]==''') )

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

    ...{

介紹一個可用于BREW的XML解析實作

        cbData-=2;

介紹一個可用于BREW的XML解析實作

        lpszNew=MALLOC((cbData+1)*sizeof(TCHAR));

介紹一個可用于BREW的XML解析實作

        if(lpszNew)

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

        ...{

介紹一個可用于BREW的XML解析實作

            MEMCPY(lpszNew,lpszData+1,(cbData)*sizeof(TCHAR));

介紹一個可用于BREW的XML解析實作

            lpszNew[cbData]=(TCHAR)NULL;

介紹一個可用于BREW的XML解析實作

        }

介紹一個可用于BREW的XML解析實作

    }

介紹一個可用于BREW的XML解析實作

    else

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

    ...{

介紹一個可用于BREW的XML解析實作

        lpszNew = MALLOC((cbData+1) * sizeof(TCHAR));

介紹一個可用于BREW的XML解析實作

        if (lpszNew)

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

        ...{

介紹一個可用于BREW的XML解析實作

            MEMCPY(lpszNew, lpszData, (cbData) * sizeof(TCHAR));

介紹一個可用于BREW的XML解析實作

            lpszNew[cbData] = (TCHAR)NULL;

介紹一個可用于BREW的XML解析實作

        }

介紹一個可用于BREW的XML解析實作

    }

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

    return lpszNew;

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

}

介紹一個可用于BREW的XML解析實作

同樣,在構造XML字串時,要将這個引号恢複出來,即:

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                        cb  =  McbLENSTR(pAttr -> lpszValue);

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                         if  (cb)

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                         ... {

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                            //modify by yancheng

介紹一個可用于BREW的XML解析實作

                            if( lpszMarker )

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                            ...{

介紹一個可用于BREW的XML解析實作

                                lpszMarker[nResult]=_T('=');

介紹一個可用于BREW的XML解析實作

                                lpszMarker[nResult+1]=_T('"');

介紹一個可用于BREW的XML解析實作

                                _tcscpy(&lpszMarker[nResult+2],pAttr->lpszValue);

介紹一個可用于BREW的XML解析實作

                                lpszMarker[nResult+1+cb+1]=_T('"');

介紹一個可用于BREW的XML解析實作

                            }

介紹一個可用于BREW的XML解析實作

                            nResult += cb+1+2;

介紹一個可用于BREW的XML解析實作

                        }

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                         if  (lpszMarker)

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                         ... {

介紹一個可用于BREW的XML解析實作

                            lpszMarker[nResult] = _T(' ');                              

介紹一個可用于BREW的XML解析實作

                        }

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

                        nResult ++ ;              

介紹一個可用于BREW的XML解析實作

                    }

介紹一個可用于BREW的XML解析實作

                }

介紹一個可用于BREW的XML解析實作

                 break ;

介紹一個可用于BREW的XML解析實作

我已經将修改後的這兩個檔案打包放在我的資源中了,可以直接下載下傳使用:http://download.csdn.net/source/313498

最後,簡要介紹一下它的使用方法,可參看MCBXml.h中的函數定義,其實是很友善的。

如何解析XML檔案,隻需要簡單地調用McbParseXML完成解析操作,傳入的第一個參數是一個XML的字串,傳回值是一個McbXMLElement結構類型的變量,McbXMLElement結構定義如下:

介紹一個可用于BREW的XML解析實作

typedef  struct  McbXMLElement

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

... {

介紹一個可用于BREW的XML解析實作

LPTSTR lpszName;  //元素名稱

介紹一個可用于BREW的XML解析實作

int nSize;               //子節點的個數

介紹一個可用于BREW的XML解析實作

int nMax;             // 最大配置設定的節點個數

介紹一個可用于BREW的XML解析實作

int nIsDeclaration;  //是否子節點是XML格式

介紹一個可用于BREW的XML解析實作

struct McbXMLNode *pEntries; //子節點數組

介紹一個可用于BREW的XML解析實作

struct McbXMLElement *pParent; //父節點

介紹一個可用于BREW的XML解析實作

}  McbXMLElement;

由此看出,通過它就可以通路到整個XML的DOM樹上的任何一個節點資料了。例如這樣:

介紹一個可用于BREW的XML解析實作

// 加載背景圖

介紹一個可用于BREW的XML解析實作

for (i = 0 ;i < pXNode -> node.pElement -> nSize;i ++ )

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

... {

介紹一個可用于BREW的XML解析實作

if(pXNode->node.pElement->pEntries[i].type==eNodeAttribute && STRICMP("background",pXNode->node.pElement->pEntries[i].node.pAttrib->lpszName)==0)

介紹一個可用于BREW的XML解析實作
介紹一個可用于BREW的XML解析實作

...{

介紹一個可用于BREW的XML解析實作

pMe->m_pImageBk=ISHELL_LoadImage(pMe->m_pIShell,pXNode->node.pElement->pEntries[i].node.pAttrib->lpszValue);

介紹一個可用于BREW的XML解析實作

if(pMe->m_pImageBk)

介紹一個可用于BREW的XML解析實作

pMe->m_isOwnBk=TRUE;

介紹一個可用于BREW的XML解析實作

break;

介紹一個可用于BREW的XML解析實作

}

介紹一個可用于BREW的XML解析實作

}

這裡的pXNode是一個McbXMLNode結構類型的指針變量。

至于如何建立或修改DOM樹的内容,也有相應的函數,具體可以參看頭檔案中的函數定義。我就不羅嗦了。有問題可以與我聯系。

繼續閱讀