介绍一个可用于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之类的。

#include "AEEStdLib.h"
    #define _T(name)    (name)
#define _tcscpy(a,b)    STRCPY(a,b)
#define _tcsstr(a,b)    STRSTR(a,b)
#define _tcschr(a,b)    STRCHR(a,b)
#define _tcslen(a)        STRLEN(a)
#define _tcsnicmp(a,b,c)  STRNICMP(a,b,c)

在MCBXml.c中,还有一个操作,我将函数McbGetError整个给注掉了(就是为了省事,如果你还要保留这个函数,额外做些工作就可以了)。

还有一个McbClearTags()函数的修改如下:

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;

}
/* McbGetClearTags */

在函数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);
    }

    
return  pElement;

要想编译通过,还有一个地方要注意的,所有的assert也掉处理掉。经过上述处理,现在这两个文件MCBXml.h/MCBXml.c已经可以嵌入我们的BREW工程中编译成功了。

不过,因为它缺省使用的属性值是不带双引号的,所以还需要做一点修改方便使用:

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;

}
/* McbStrdup */

同样,在构造XML字串时,要将这个引号恢复出来,即:

                        /*
                        *****************************************************
                        * "Attrib=Value "
                        *****************************************************
                        
*/

                        cb 
=  McbLENSTR(pAttr -> lpszValue);

                        
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;
                        }


                        
if  (lpszMarker)
                        
{
                            lpszMarker[nResult] 
= _T(' ');                              
                        }


                        nResult
++ ;              
                    }
                }
                
break ;

我已经将修改后的这两个文件打包放在我的资源中了,可以直接下载使用:http://download.csdn.net/source/313498

最后,简要介绍一下它的使用方法,可参看MCBXml.h中的函数定义,其实是很方便的。

如何解析XML文件,只需要简单地调用McbParseXML完成解析操作,传入的第一个参数是一个XML的字串,返回值是一个McbXMLElement结构类型的变量,McbXMLElement结构定义如下:

typedef  struct  McbXMLElement
{
LPTSTR lpszName;  
//元素名称
int nSize;               //子节点的个数
int nMax;             // 最大分配的节点个数
int nIsDeclaration;  //是否子节点是XML格式
struct McbXMLNode *pEntries; //子节点数组
struct McbXMLElement *pParent; //父节点
}
 McbXMLElement;

由此看出,通过它就可以访问到整个XML的DOM树上的任何一个节点数据了。例如这样:

// 加载背景图
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树的内容,也有相应的函数,具体可以参看头文件中的函数定义。我就不罗嗦了。有问题可以与我联系。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值