高通在BREW平台中并沒有為我們提供一個可以友善使用的API來實作XML檔案的解析,在很多情況下,我們需要操作一個XML檔案。就這事我曾電話咨詢過博路的工程師,他給出的答複是可以購買一個商業元件來實作這個功能。事實上,沒必要如此複雜,我們完全可以利用網際網路上的免費的開源代碼來實作這個功能。
本文要介紹的開源代碼就是:Martyn C Brown為我們提供的一個完全基于ANSI C實作的MCBXml。
這是一個很純的标準C實作,是以,要移植到BREW上是比較容易的。
第一步:我們直接把它揣進一個BREW工程中,編譯一下,就會發現很多的編譯錯誤出來了。(這一步的目的就是要看看它都有哪些東西不符合BREW的要求,這正是我們需要修改的地方)。
第二步:現在可以修改代碼了,簡單地利用#define将它使用的一些函數替換成BREW可以接受的形式。當然在這之前先移掉幾個頭引用,加入BREW的引用。對于頭檔案的修改就這麼簡單而已。而對于MCBXml.c的修改其它除了用#define來替換以外,還有一種方法就是“查找替換”法,呵呵,比如free換成FREE,malloc換成MALLOC之類的。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
#include "AEEStdLib.h" #define _T(name) (name)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
#define _tcscpy(a,b) STRCPY(a,b)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
#define _tcsstr(a,b) STRSTR(a,b)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
#define _tcschr(a,b) STRCHR(a,b)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
#define _tcslen(a) STRLEN(a)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
#define _tcsnicmp(a,b,c) STRNICMP(a,b,c)
在MCBXml.c中,還有一個操作,我将函數McbGetError整個給注掉了(就是為了省事,如果你還要保留這個函數,額外做些工作就可以了)。
還有一個McbClearTags()函數的修改如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
McbClearTag * McbGetClearTags()
... {
struct McbClearTag * tags = (McbClearTag*)MALLOC(sizeof(McbClearTag)*6);
//struct McbClearTag tags[] =
//{
// { _T("<![CDATA["), _T("]]>") },
// { _T("<PRE>"), _T("</PRE>") },
// { _T("<Script>"), _T("</Script>") },
// { _T("<!--"), _T("-->") },
// { _T("<!DOCTYPE"), _T(">") },
// { NULL, NULL }
//};
MEMSET(tags,0,sizeof(McbClearTag)*6);
tags[0].lpszOpen=STRDUP("<![CDATA[");
tags[0].lpszClose=STRDUP("]]>");
tags[1].lpszOpen=STRDUP("<PRE>");
tags[1].lpszClose=STRDUP("</PRE>");
tags[2].lpszOpen=STRDUP("<!--");
tags[2].lpszClose=STRDUP("-->");
tags[3].lpszOpen=STRDUP("<!DOCTYPE");
tags[3].lpszClose=STRDUP(">");
tags[4].lpszOpen=STRDUP("<Script");
tags[4].lpszClose=STRDUP("</Script>");
tags[5].lpszOpen=NULL;
tags[5].lpszClose=NULL;
return tags;
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
在函數McbXMLElement * McbParseXML(LPCTSTR lpszXML, McbXMLResults *pResults)的實作中,最後還要注意釋放掉上面弄出來的字串:
... ... ... {
int i;
for(i=0;i<6;i++)
...{
FREEIF(xml.pClrTags[i].lpszOpen);
FREEIF(xml.pClrTags[i].lpszClose);
}
FREEIF(xml.pClrTags);
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
return pElement;
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
要想編譯通過,還有一個地方要注意的,所有的assert也掉處理掉。經過上述處理,現在這兩個檔案MCBXml.h/MCBXml.c已經可以嵌入我們的BREW工程中編譯成功了。
不過,因為它預設使用的屬性值是不帶雙引号的,是以還需要做一點修改友善使用:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
LPTSTR McbStrdup(LPCTSTR lpszData, int cbData)
... {
//以下是新的邏輯 by YanCheng(2007-12-14)
//去掉引号
LPTSTR lpszNew;
if( cbData==0 ) cbData = _tcslen(lpszData);
if( (lpszData[0]=='"' && lpszData[cbData-1]=='"') || (lpszData[0]==''' && lpszData[cbData-1]==''') )
...{
cbData-=2;
lpszNew=MALLOC((cbData+1)*sizeof(TCHAR));
if(lpszNew)
...{
MEMCPY(lpszNew,lpszData+1,(cbData)*sizeof(TCHAR));
lpszNew[cbData]=(TCHAR)NULL;
}
}
else
...{
lpszNew = MALLOC((cbData+1) * sizeof(TCHAR));
if (lpszNew)
...{
MEMCPY(lpszNew, lpszData, (cbData) * sizeof(TCHAR));
lpszNew[cbData] = (TCHAR)NULL;
}
}
return lpszNew;
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
同樣,在構造XML字串時,要将這個引号恢複出來,即:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
cb = McbLENSTR(pAttr -> lpszValue);
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
if (cb)
... {
//modify by yancheng
if( lpszMarker )
...{
lpszMarker[nResult]=_T('=');
lpszMarker[nResult+1]=_T('"');
_tcscpy(&lpszMarker[nResult+2],pAttr->lpszValue);
lpszMarker[nResult+1+cb+1]=_T('"');
}
nResult += cb+1+2;
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
if (lpszMarker)
... {
lpszMarker[nResult] = _T(' ');
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
nResult ++ ;
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
break ;
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
我已經将修改後的這兩個檔案打包放在我的資源中了,可以直接下載下傳使用:http://download.csdn.net/source/313498
最後,簡要介紹一下它的使用方法,可參看MCBXml.h中的函數定義,其實是很友善的。
如何解析XML檔案,隻需要簡單地調用McbParseXML完成解析操作,傳入的第一個參數是一個XML的字串,傳回值是一個McbXMLElement結構類型的變量,McbXMLElement結構定義如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
typedef struct McbXMLElement
... {
LPTSTR lpszName; //元素名稱
int nSize; //子節點的個數
int nMax; // 最大配置設定的節點個數
int nIsDeclaration; //是否子節點是XML格式
struct McbXMLNode *pEntries; //子節點數組
struct McbXMLElement *pParent; //父節點
} McbXMLElement;
由此看出,通過它就可以通路到整個XML的DOM樹上的任何一個節點資料了。例如這樣:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
// 加載背景圖
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUmbv50LcNncvRXYjlGZul0ZulmbpxGd190LcdmbpRHanlGbodWaohXY05Wez9CX0Vmbu4GZzNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.gif)
for (i = 0 ;i < pXNode -> node.pElement -> nSize;i ++ )
... {
if(pXNode->node.pElement->pEntries[i].type==eNodeAttribute && STRICMP("background",pXNode->node.pElement->pEntries[i].node.pAttrib->lpszName)==0)
...{
pMe->m_pImageBk=ISHELL_LoadImage(pMe->m_pIShell,pXNode->node.pElement->pEntries[i].node.pAttrib->lpszValue);
if(pMe->m_pImageBk)
pMe->m_isOwnBk=TRUE;
break;
}
}
這裡的pXNode是一個McbXMLNode結構類型的指針變量。
至于如何建立或修改DOM樹的内容,也有相應的函數,具體可以參看頭檔案中的函數定義。我就不羅嗦了。有問題可以與我聯系。