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

前端之家收集整理的这篇文章主要介绍了【备忘录】libxml解析文档时两个常见问题的解决办法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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

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


问题一:

Entity: line 1: parser error : XML declaration allowed only at the start of the document
 <?xml ve
      ^
Entity: line 1: parser error : Char 0x0 out of allowed range
 <?xml ve
         ^
Entity: line 1: parser error : Char 0x0 out of allowed range
 <?xml ve
         ^
Entity: line 1: parser error : ParsePI: PI xml never end ...
 <?xml ve
         ^
Entity: line 1: parser error : Start tag expected,'<' not found
 <?xml ve
         ^
read file error

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


(一)原因在发送端。

发送端使用到一个函数

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,strlen(str)+1 );

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


(二)原因在接收端

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

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

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

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

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


问题二:

Entity: line 1: parser error : XML declaration allowed only at the start of the document
 <?xml version="1.0" encoding="utf8"?>
      ^
read file error

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

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

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

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

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

原文链接:https://www.f2er.com/xml/298443.html

猜你在找的XML相关文章