zoukankan      html  css  js  c++  java
  • charactersFound方法中的陷阱

    libxml2恐怕是linux下最著名的xml解析库了,其sax API不仅解析效率高,速度快,而且内存占用率更是出奇的低。因此是iphone开发中必不可少的xml解析库。

    但sax解析是基于事件驱动的,使用门槛较dom解析为高,不容易为初学者掌握,代码难于阅读和理解。比如笔者写过这样的代码:

    //解析元素体时触发

    - (void)charactersFound:(const xmlChar*)ch

    len:(int)len

    {       

    NSString*   string;

    string = [[NSString alloc] initWithBytes:ch length:len encoding:NSUTF8StringEncoding];

        // login_status元素体

        switch (flag) {

    case 1:

    [item setObject:string forKey:@"GNID"];

    break;

    case 2:

    [item setObject:string forKey:@"YWBH"];

    break;

    case 3:

    [item setObject:string forKey:@"QDRQ"];

    break;

        }

    }

    表面上看这段代码没有任何问题,实际上却隐藏着致命的陷阱。
    这是因为,当libxml2在解析一个元素体时,会不只一次的回调charactersFound方法!
    也就是说一个元素,需要好几次的回调,libxml才会解析出元素体文本。
    具体说,标签体文本如果包含多种编码(比如:ipcc日报,同时包含两种字符:asciiutf8编码),那么,libxml2会在解析“ipcc”时调用一次charactersFound方法,然后在“日报”两个字时再次回调charactersFound方法。
    因此上面的代码应该做如下修改:
    把局部变量string声明为全局的NSMutableString类型。
    修改上述方法代码为:

    - (void)charactersFound:(const xmlChar*)ch

    len:(int)len

    {       

    [string appendString:[[NSString alloc] initWithBytes:ch length:len encoding:NSUTF8StringEncoding]];

    }
    然后在元素结束标记回调方法中取得整个string的内容:

    //解析元素结束标记时触发

    - (void)endElementLocalName:(const xmlChar*)localname

    prefix:(const xmlChar*)prefix URI:(const xmlChar*)URI

    {

    switch (flag) {

    case 1:

    [item setObject:string forKey:@"GNID"];

    break;

    case 2:

    [item setObject:string forKey:@"YWBH"];

    break;

    case 3:

    [item setObject:string forKey:@"QDRQ"];

    break;

    }

    flag=0;

    }

    然后在元素开始标记回调方法startElementLocalName中,重置string变量:

    [string release];

        string=[[NSMutableString alloc]init];


  • 相关阅读:
    清除vs2005、vs2008起始页最近打开项目
    解决VS2005打开js,css,asp.php等文件,中文都是乱码的问题
    “007~ASP 0104~不允许操作”错误的解决方法(图解)
    nofollow标签浪费了多少站长做外链的时间
    如果你的评论被WordPress的Akismet插件屏蔽,怎么解封?
    VPS磁盘划分建立新磁盘
    ASP.NET使用AJAX应注意IIS有没有.ashx扩展
    将磁盘从FAT格式转换为NTFS格式的方法
    C#调用RabbitMQ实现消息队列(转载)
    超燃:2019 中国.NET 开发者峰会视频发布
  • 原文地址:https://www.cnblogs.com/encounter/p/2188524.html
Copyright © 2011-2022 走看看