当前位置: 首页 > 工具软件 > libroxml > 使用案例 >

发现libroxml不能处理XML中的转义字符

朱鹤轩
2023-12-01

    XML 规范中定义了以下转义字符:

符号
说明
替换值
<小于&lt;
>大于&gt;
&逻辑与&amp;
'单引号&apos;
"双引号&quot;

    当 XML 的元素值为上表中的特殊符号时,在 XML 中表示这些符号时要用规定的替换值。

    libroxml 是一个用 C 语言开发的开源 XML 解析工具,它在 github 上的网址是:https://github.com/blunderer/libroxml,优点是比较小巧。我在使用过程中发现 libroxml 不能处理转义字符。比如有一个名为 MyConfig.xml 的 XML 文件,其内容如下:

<configure>
<hardware_name>TestCircuitBoard&amp;1</hardware_name>
<hardware_count>10</hardware_count>
<configure>

    写一个 C 程序调用 libroxml 获取文件中的元素值,内容如下:

/**************************************************   
* Author: HAN Wei   
* Author's blog: http://blog.csdn.net/henter/   
* Date: April 1st, 2017
* Description: demonstrate that XML escape characters
  cannot be translated by libroxml
**************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "roxml.h"

int main(void)
{
  node_t *root_node, *config_node, *hd_name_node, *text_node;
  char hd_name[128];

  memset(hd_name, 0, sizeof(hd_name));
  if ( !(root_node = roxml_load_doc("MyConfig.xml")) )
  {
    printf("Load config XML file failed at %s, line %d!\n", __FILE__, __LINE__);
	return (-1);
  }

  if ( !(config_node = roxml_get_chld(root_node, NULL, 0)) )
  {
	printf("Search node in config XML file failed at %s, line %d!\n", __FILE__, __LINE__);
	roxml_close(root_node);
	return (-1);
  }

  if ( !(hd_name_node = roxml_get_nodes(config_node, ROXML_ELM_NODE, "hardware_name", 0)) )
  {
	printf("Search node in config XML file failed at %s, line %d!\n", __FILE__, __LINE__);
	roxml_close(root_node);
	return (-1);
  }

  if ( !(text_node = roxml_get_txt(hd_name_node, 0)) )
  {
	printf("Search node in config XML file failed at %s, line %d!\n", __FILE__, __LINE__);
	roxml_close(root_node);
	return (-1);
  }

  if ( strlen(roxml_get_content(text_node, NULL, 0, NULL)) > sizeof(hd_name) )
  {
	printf("Hardware name byte length is beyond the upperbound in config XML file at %s, line %d!\n", __FILE__, __LINE__);
	roxml_close(root_node);
	return (-1); 
  }
  strcpy(hd_name, roxml_get_content(text_node, NULL, 0, NULL));
  printf("hardware name in XML file: %s\n", hd_name);

  roxml_close(root_node);
#if defined(_WIN32) || defined(_WIN64)
  system("pause");
#endif
  return 0;
} 

    使用 2.3.0 版本的libroxml,程序运行的结果为:hardware name in XML file: TestCircuitBoard&amp;1

    而期望的结果是: hardware name in XML file: TestCircuitBoard&1

    这说明 libroxml 不能处理 XML 中的转义字符,至少在 2.3.0 及更早的版本中存在此问题。已经在 github 上向开发者反馈了这个问题,希望能在后继版本中修复。

——————————————————————————————————

    如果使用另外一个 C 语言开发的 XML 解析工具 Mini-XML (网址:https://github.com/michaelrsweet/mxml),当读取 XML 中的元素值时,它能够正确转换其中的转义字符。比如在取出的字符串中自动将 &amp; 转换成 &。在向 XML 中写入元素值时,它也能够正确转换,比如要写入 & 时,Mini-XML 会自动将 & 转换成 &amp;  ,然后向 XML 文件中写入 &amp;  。 


    对于使用 C++ 开发的开源 XML 解析工具 TinyXML-2,它也能正确地转换转义字符。在其网站 http://www.grinninglizard.com/tinyxml2docs/index.html 上的说明如下:
    TinyXML-2 recognizes the pre-defined "character entities", meaning special characters. Namely:
&amp;   &
&lt;    <
&gt;    >
&quot;  "
&apos;  '
    These are recognized when the XML document is read, and translated to their UTF-8 equivalents. For instance, text with the XML of: Far &amp; Away will have the Value() of "Far & Away" when queried from the XMLText object, and will be written back to the XML stream/file as an ampersand.



 类似资料: