为了提高duilib创建布局控件的效率,在LuaDui项目中使用rapidxml解析器替换了duilib库自带的xml解析器。

duilib使用unicode编译,所以rapidxml需要解析unicode xml字符串。

  使用rapidxml解析unicode字符串很简单,只需在rapidxml的模板参数中设置为TCHAR即可,所以定义以下类型方便使用。

  1. #include <rapidxml/rapidxml.hpp>
  2. typedef rapidxml::xml_document<TCHAR> XmlDoc;
  3. typedef rapidxml::xml_node<TCHAR> XmlNode;
  4. typedef rapidxml::xml_attribute<TCHAR> XmlAttr;

  在使用过程中发现了解析xml中的中文字符出现bug,解析如下xml会出现问题抛出异常。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Window caption="0,0,0,30" sizebox="5,5,5,5" mininfo="480,360" defaultfontcolor="#ff010000" width="600" height="480">
  3. <Font name="微软雅黑" size="12" bold="false"/>
  4.  
  5. <VerticalLayout bkcolor="#ff019bd0" inset="1,1,1,1" bordersize="1" bordercolor="#FF010000">
  6. <HorizontalLayout height="30" inset="5,0,0,0">
  7. <Label name="标题" text="调试窗口" textcolor="#FFFFFFFF"></Label>
  8. <Control />
  9. <Button name="minbtn" width="40" height="22" text="最小化" bkcolor="#ff3fd536">
  10.   <Event click="DebugUIEvent.minBtnClick" />
  11. </Button>
  12. <Button name="closebtn" width="47" height="22" text="关闭" bkcolor="#ffef2f4d">
  13.   <Event click="DebugUIEvent.closeBtnClick" />
  14. </Button>
  15. </HorizontalLayout>
  16.  
  17.   <VerticalLayout bkcolor="#66ffffff">
  18.  
  19.   </VerticalLayout>
  20. </VerticalLayout>
  21. </Window>

  断点时发现在解析 text="最小化" 属性时出现问题,解析text值的时候把后面的内容全部当做text的属性值,无法再往下解析了。

最后终于找到了问题所在,rapidxml为提高解析效率,定义了如下的表:

  1. template<int Dummy>
  2. struct lookup_tables
  3. {
  4. static const unsigned char lookup_whitespace[256]; // Whitespace table
  5. static const unsigned char lookup_node_name[256]; // Node name table
  6. static const unsigned char lookup_text[256]; // Text table
  7. static const unsigned char lookup_text_pure_no_ws[256]; // Text table
  8. static const unsigned char lookup_text_pure_with_ws[256]; // Text table
  9. static const unsigned char lookup_attribute_name[256]; // Attribute name table
  10. static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote
  11. static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote
  12. static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes
  13. static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes
  14. static const unsigned char lookup_digits[256]; // Digits
  15. static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters
  16. };

  来识别xml中的标志符,在进行查找的时候直接通过数组直接找到使用了

如下操作:

internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];

但在unicode下static_cast<unsigned char>(ch)的ch是wchar占两个字节直接转换为unsigned char会出现判断出错问题。所以要在rapidxml中解析unicode需要修改rapidxml代码:

  1. // Detect whitespace character
  2. struct whitespace_pred
  3. {
  4. static unsigned char test(Ch ch)
  5. {
  6. if(ch<=255)
  7. return internal::lookup_tables<0>::lookup_whitespace[static_cast<unsigned char>(ch)];
  8. else
  9. return 0;
  10. }
  11. };
  12.  
  13. // Detect node name character
  14. struct node_name_pred
  15. {
  16. static unsigned char test(Ch ch)
  17. {
  18. if(ch<=255)
  19. return internal::lookup_tables<0>::lookup_node_name[static_cast<unsigned char>(ch)];
  20. else
  21. return 1;
  22. }
  23. };
  24.  
  25. // Detect attribute name character
  26. struct attribute_name_pred
  27. {
  28. static unsigned char test(Ch ch)
  29. {
  30. if(ch<=255)
  31. return internal::lookup_tables<0>::lookup_attribute_name[static_cast<unsigned char>(ch)];
  32. else
  33. return 1;
  34. }
  35. };
  36.  
  37. // Detect text character (PCDATA)
  38. struct text_pred
  39. {
  40. static unsigned char test(Ch ch)
  41. {
  42. if(ch<=255)
  43. return internal::lookup_tables<0>::lookup_text[static_cast<unsigned char>(ch)];
  44. else
  45. return 1;
  46. }
  47. };
  48.  
  49. // Detect text character (PCDATA) that does not require processing
  50. struct text_pure_no_ws_pred
  51. {
  52. static unsigned char test(Ch ch)
  53. {
  54. if(ch<=255)
  55. return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];
  56. else
  57. return 1;
  58. }
  59. };
  60.  
  61. // Detect text character (PCDATA) that does not require processing
  62. struct text_pure_with_ws_pred
  63. {
  64. static unsigned char test(Ch ch)
  65. {
  66. if(ch<=255)
  67. return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast<unsigned char>(ch)];
  68. else
  69. return 1;
  70. }
  71. };
  72.  
  73. // Detect attribute value character
  74. template<Ch Quote>
  75. struct attribute_value_pred
  76. {
  77. static unsigned char test(Ch ch)
  78. {
  79.  
  80. if (Quote == Ch('\''))
  81. if(ch<=255)
  82. return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast<unsigned char>(ch)];
  83. else
  84. return 1;
  85. if (Quote == Ch('\"'))
  86. if(ch<=255)
  87. return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast<unsigned char>(ch)];
  88. else
  89. return 1;
  90. return 0; // Should never be executed, to avoid warnings on Comeau
  91. }
  92. };
  93.  
  94. // Detect attribute value character
  95. template<Ch Quote>
  96. struct attribute_value_pure_pred
  97. {
  98. static unsigned char test(Ch ch)
  99. {
  100. if (Quote == Ch('\''))
  101. if(ch<=255)
  102. return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];
  103. else
  104. return 1;
  105. if (Quote == Ch('\"'))
  106. if(ch<=255)
  107. return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];
  108. else
  109. return 1;
  110. return 0; // Should never be executed, to avoid warnings on Comeau
  111. }
  112. };

  

rapidxml对unicode的支持的更多相关文章

  1. 各个系统和语言对Unicode的支持 字符集和编码——Unicode(UTF&UCS)深度历险

    http://www.cnblogs.com/Johness/p/3322445.html 各个系统和语言对Unicode的支持: Windows NT从底层支持Unicode(不幸的是,Window ...

  2. C++的标准库函数默认都是操作字节,而不是字符,非常痛苦,所以引入了u16string和u32string(Linux上的wchar_t是32位的原因,utf16对unicode的支持是有缺陷的)good

    时至今日,字符串使用unicode已经是不需要理由的常识,但对一些有着悠久历史的编程语言来说,这仍然是个头痛的问题.如果抛开第三方库的支持,C++其实并不能实际有效地支持unicode,即使是utf8 ...

  3. 本地win7 把数组写入 txt 文本日志 json_encode转换中文,需要加上JSON_UNESCAPED_UNICODE 不适用unicode --仅仅支持php5.4以后

    json_encode 改进 为 json_encode_ex function json_encode_ex($value){ if (version_compare(PHP_VERSION, '5 ...

  4. Erlang的Unicode支持

    在R13A中, Erlang加入了对Unicode的支持.本文涉及到的数据类型包括:list, binary, 涉及到的模块包括stdlib/unicode, stdlib/io, kernel/fi ...

  5. [Erlang 0124] Erlang Unicode 两三事 - 补遗

    最近看了Erlang User Conference 2013上patrik分享的BRING UNICODE TO ERLANG!视频,这个分享很好的梳理了Erlang Unicode相关的问题,基本 ...

  6. 【Windows编程】系列第四篇:使用Unicode编程

    上一篇我们学习了Windows编程的文本及字体输出,在以上几篇的实例中也出现了一些带有“TEXT”的Windows宏定义,有朋友留言想了解一些ANSI和Unicode编程方面的内容,本章就来了解和学习 ...

  7. boost::spirit unicode 简用记录

    本文简单记录使用boost::spirit解析有中文关键字的字符串并执行响应动作,类似于语法分析+执行. 关键字:字符串解析 boost::spirit::qi::parse qi::unicode: ...

  8. 彻底搞定char/wchar_t/unicode

    彻底搞定char/wchar_t!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! (2013-07-17 10:18:28) 转载▼     从char/wchar_t到TCHAR(1) ...

  9. [Python] 中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题

    最近研究搜索引擎.知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前.虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下 ...

随机推荐

  1. openstack 正常流量

  2. javascript获取元素的计算样式

    使用css控制页面有4种方式,分别为行内样式(内联样式).内嵌式.链接式.导入式. 行内样式(内联样式)即写在html标签中的style属性中,如<div style="width:1 ...

  3. CSS3最简洁的轮播图

    <!DOCTYPE html> <html> <head> <title>CSS3最简洁的轮播图</title> <style> ...

  4. Git简介:

    Git中文文档 1.详解在Visual Studio中使用git版本系统(图文) 2.GitExtensions下载地址:http://gitextensions.codeplex.com/ 3.Gi ...

  5. Python 函数和模块

    200 ? "200px" : this.width)!important;} --> 介绍 在python中也存在函数的概念,标准的函数我们可以叫内置函数,这类函数可以直接 ...

  6. 如何去掉WinForm或者WPF的最大化和最小化按钮

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何去掉WinForm或者WPF的最大化和最小化按钮.

  7. asp.net Mvc+bootstarp+esayUI+EF 框架(一)

       "框架" 这两个字从通俗的意义来讲就是提高复用性,解耦类之间的关系和方便开发人员开发.   使用的技术也是大家基本现在都用过的,而这个系类我所要讲的内容是什么呢? 框架的基本 ...

  8. iOS开发中懒加载的使用和限制

    1.在开发过程中很多时候,很多控件和对象需要alloc为了,提高开发效率使得懒加载得以产生. 2.下边用代码解释: - (NSMutableArray *)newsArr{ if (!_newsArr ...

  9. SqlServer数据库的一些方法的用途

    一直分不清这三种方法的具体用法现在终于找齐了 ExecuteNonQuery方法和ExecuteScalar方法和ExecuteReader方法的区别 (1)ExecuteNonQuery():执行命 ...

  10. MFC TreeCtrl 控件(一):简单使用

    本文描写叙述了 MFC 中的树形控件 TreeCtrl 的简单使用,内容包含数据项的加入.图标设置.提示信息设置等. 新建基于对话框的应用程序,加入一个 TreeCtrl ,为其定义一个控件变量 m_ ...