【备忘录】libxml解析文档时两个常见问题的解决办法

之前在做的一个小项目,需要使用套接字发送xml,所以使用到了libxml这个库(基本用法在上一篇文章有说)。

在发送端监测的xml字符串明明还是正常的,到了接收端就各种收不全,不然就是收到了然后解析错误,查资料也没找到类似的问题,弄得神烦。

今天终于把问题解决了,记一下解决办法当作备忘录。


问题一:

Entity: line 1: parser error : XML declaration allowed only at the start of the document
 

这个问题是收不全。有两种可能性。


(一)原因在发送端。

发送端使用到一个函数:

 xmlDocDumpFormatMemoryEnc(xmlDocPtr xDoc, &xmlChar * str, &int str_length, "utf8", 1) 

这个函数 是将生成好的xmlDocPtr变量中的xml转换为字符串存到str中,然后我们就可以将这个str通过write发送到接收端。这是基本原理。

但是!在write的时候我是这么写的:write(connect_fd, str, sizeof(str) );

于是就有了问题。这里sizeof(str)的长度是str这个指针的长度,等于4,而不是我们字符串的长度,所以导致了这个问题。

解决办法:改写为write(connect_fd, str, strlen(str)+1 );

注意最后要strlen(str)后面要+1,为了保证'\0'保持字符串完整。


(二)原因在接收端

接收端因为我使用的是epoll的边缘触发事件响应,所以需要while( recbytes > 0 ){ read( ); }这样来读取。

但是!在发送端,因为libxml的一些问题,xml字符串时候遇到空格,【write() read()】函数会将这个包断开,这就导致了出现接收到

解决办法:while( recbytes > 0 ){ read( ); }中添加拼接函数strncpy函数(之所以不用sprintf我会在下面说)

修改后的代码是这样:while( recbytes =read(connect_fd, buffer, MAXSIZE) ){ strncpy(str, buffer, sizeof(buffer) ); } return str;

这样将每次收到的字符串buffer拼接为str,即可。


问题二:

Entity: line 1: parser error : XML declaration allowed only at the start of the document
 
      ^
read file error

这个问题的成因在接收端。错误名: 只允许 文档的开始进行 XML声明。

这个属于我误操作导致的。

这里我用到的拼接函数(拼接函数在上面的(二)原因在接收端提到)是sprintf(str, "%s%s", str, buffer)。

这个函数没有问题,问题在于我初始化字符串str时将其初始化为{' '},多了个空格。这样xml开头就是一个空格,而不是xml的声明,导致了这个错误。

解决办法:很简单,对str初始化为空,或者不对str初始化就行了。



你可能感兴趣的:(xml,备忘录)