免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2393 | 回复: 5

[C++] tinyXML解析 [复制链接]

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-07-01 22:20:00
发表于 2016-05-11 16:43 |显示全部楼层
本帖最后由 18225629625 于 2016-05-11 16:53 编辑

最近项目中使用C、C++混编,需要解析XML,操作的流程是读取本地的XML文件,获取buf,然后使用tinyXML解析
操作如下:
//根据数据中心传过来的XMLBuf获得本模块需要的UpdataTime
extern "C"  void OHSERVER_InitModule(char *pBuffer)
{
        C_DEBUG;

        //将XML存储到本模块的BUFFER中
        char xmlbuf[4096] = "";
        strcpy(xmlbuf, pBuffer);

        XMLHelper OHxmlHelp(xmlbuf);
        NodeInfor nodeInfor;

        ClearNodeVar();
        //UpdataTime
        OHxmlHelp.ReadNode((char *)"root/OHCloud/Time", nodeInfor);
        UpdataTime = atoi(OHxmlHelp.EasyReadNodeAttributeValue(nodeInfor, "TimeUpData").c_str());

        //UpdataTime = 10;
        printf("UpdataTime = %d\n", UpdataTime);
}

但是有的时候会在创建对象的时候就提示下列错误:
“void TixmlParsingData::Stamp(const char *, TixmlEncoding): Assertion `cursor.col >= -1` failed。


XMLHelper的构造函数如下:
XMLHelper::XMLHelper(char* pbuf)
{
        m_pbuffer = new char[1024*100];
        memset(m_pbuffer,0,1024*100);

        if(pbuf)
                strcpy(m_pbuffer,pbuf);
        else
                strcpy(m_pbuffer,"<?xml version=\"1.0\" encoding=\"GBK\"?>");

        m_pDoc = new TiXmlDocument(m_pbuffer);

}

再往下追踪到发生错误的地方,功力太低,搞不明白了
void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
{
        assert( now );

        // Do nothing if the tabsize is 0.
        if ( tabsize < 1 )
        {
                return;
        }

        // Get the current row, column.
        int row = cursor.row;
        int col = cursor.col;
        const char* p = stamp;
        assert( p );

        while ( p < now )
        {
                // Treat p as unsigned, so we have a happy compiler.
                const unsigned char* pU = (const unsigned char*)p;

                // Code contributed by Fletcher Dunn: (modified by lee)
                switch (*pU) {
                        case 0:
                                // We *should* never get here, but in case we do, don't
                                // advance past the terminating null character, ever
                                return;

                        case '\r':
                                // bump down to the next line
                                ++row;
                                col = 0;                               
                                // Eat the character
                                ++p;

                                // Check for \r\n sequence, and treat this as a single character
                                if (*p == '\n') {
                                        ++p;
                                }
                                break;

                        case '\n':
                                // bump down to the next line
                                ++row;
                                col = 0;

                                // Eat the character
                                ++p;

                                // Check for \n\r sequence, and treat this as a single
                                // character.  (Yes, this bizarre thing does occur still
                                // on some arcane platforms...)
                                if (*p == '\r') {
                                        ++p;
                                }
                                break;

                        case '\t':
                                // Eat the character
                                ++p;

                                // Skip to next tab stop
                                col = (col / tabsize + 1) * tabsize;
                                break;

                        case TIXML_UTF_LEAD_0:
                                if ( encoding == TIXML_ENCODING_UTF8 )
                                {
                                        if ( *(p+1) && *(p+2) )
                                        {
                                                // In these cases, don't advance the column. These are
                                                // 0-width spaces.
                                                if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
                                                        p += 3;       
                                                else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
                                                        p += 3;       
                                                else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
                                                        p += 3;       
                                                else
                                                        { p +=3; ++col; }        // A normal character.
                                        }
                                }
                                else
                                {
                                        ++p;
                                        ++col;
                                }
                                break;

                        default:
                                if ( encoding == TIXML_ENCODING_UTF8 )
                                {
                                        // Eat the 1 to 4 byte utf8 character.
                                        int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
                                        if ( step == 0 )
                                                step = 1;                // Error case from bad encoding, but handle gracefully.
                                        p += step;

                                        // Just advance one column, of course.
                                        ++col;
                                }
                                else
                                {
                                        ++p;
                                        ++col;
                                }
                                break;
                }
        }
        cursor.row = row;
        cursor.col = col;
        assert( cursor.row >= -1 );
        assert( cursor.col >= -1 );
        stamp = p;
        assert( stamp );

小弟XML解析刚刚接触,请大虾们帮帮忙

论坛徽章:
12
2015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之同曦
日期:2017-03-17 19:13:162016科比退役纪念章
日期:2016-11-07 08:28:12luobin
日期:2016-06-17 17:46:36wusuopu
日期:2016-06-17 17:43:4515-16赛季CBA联赛之福建
日期:2016-01-14 12:49:22程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:002015年亚洲杯之科威特
日期:2015-03-24 14:21:272015年迎新春徽章
日期:2015-03-04 09:57:092016科比退役纪念章
日期:2018-04-10 16:20:18
发表于 2016-05-12 10:30 |显示全部楼层
这是 xml 库的源码吗?感觉没必要直接看源码,看接口怎么用就行了。

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-07-01 22:20:00
发表于 2016-05-13 10:52 |显示全部楼层
嗯,是的,采用的是封装好的函数接口,只不过在使用的过程中,偶尔会出现上述的错误,有点无从下手的感觉,所以求助下,看看大家有没有出现过同样的问题回复 2# VIP_fuck


   

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2016-05-13 20:23 |显示全部楼层
只取一个XPATH的值用SAX模式的XML解析器吧,推荐小巧高效的fasterxml
  1. #include "fasterxml.h"

  2. static int natoi( char *str , int len )
  3. {
  4.         char    buf[ 20 + 1 ] ;

  5.         memset( buf , 0x00 , sizeof(buf) );
  6.         strncpy( buf , str , len );

  7.         return atoi(buf);
  8. }

  9. #define XPATH           "/root/OHCloud/Time/TimeUpData"

  10. static funcCallbackOnXmlNode CallbackOnXmlNode ;
  11. int CallbackOnXmlNode( int type , char *xpath , int xpath_len , int xpath_size , char *node , int node_len , char *properties , int properties_len , char *content , int content_len , void *p )
  12. {
  13.         if( type & FASTERXML_NODE_LEAF )
  14.         {
  15.                 if( xpath_len == sizeof(XPATH)-1 && strncmp( xpath , XPATH , xpath_len ) == 0 )
  16.                 {
  17.                         int     *pUpdateTime = (int*)p ;
  18.                         (*pUpdateTime) = natoi( content , content_len ) ;
  19.                 }
  20.         }

  21.         return 0;
  22. }

  23. void OHSERVER_InitModule( char *pBuffer )
  24. {
  25.         char            xpath[ 1024 + 1 ] ;
  26.         int             UpdataTime ;
  27.         int             nret = 0 ;

  28.         memset( xpath , 0x00 , sizeof(xpath) );
  29.         nret = TravelXmlBuffer( pBuffer , xpath , sizeof(xpath)-1 , & CallbackOnXmlNode , (void*) & UpdataTime ) ;
  30.         if( nret )
  31.         {
  32.                 printf( "TravelXmlBuffer failed[%d]\n" , nret );
  33.                 return;
  34.         }

  35.         printf( "UpdataTime[%d]\n" , UpdataTime  );

  36.         return;
  37. }

  38. int main()
  39. {
  40.         /* fopen and fread and fclose */
  41.         char    xmlbuf[] = "<root><OHCloud><Time><TimeUpData>1234567890</TimeUpData></Time></OHCloud></root>" ;

  42.         OHSERVER_InitModule( xmlbuf );

  43.         return 0;
  44. }
复制代码
  1. gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -I/home/calvin/include -I/usr/local/include -I/usr/include -I/home/calvin/include/fasterxml  -c x.c
  2. gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o x x.o -L. -L/home/calvin/lib -L/usr/local/lib -L/usr/lib -L/home/calvin/lib -lfasterxml -lm
复制代码
  1. [calvin@iZ23k0yd363Z /home/calvin/src/tmp] ./x
  2. UpdataTime[1234567890]
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2016-05-13 20:25 |显示全部楼层

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-07-01 22:20:00
发表于 2016-05-16 08:40 |显示全部楼层
谢谢大侠相助,小弟收下了 回复 5# BetonArmEE


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP