这里的版本是libxml2-2.9.1,官网的API MENU写得比较简单,基本上都是轻描淡写,给人敷衍了事的感觉,只能结合源码写demo了,弄了这个取特定key的value的代码。
getXmlValue.c
#include <string.h>
#include <libxml/xmlreader.h>
#include "logger.h"
//#ifdef LIBXML_READER_ENABLED
int getValueFromXMLFile(const char * key,const char * file,unsigned char * buf_out,size_t buf_len){
if(NULL == key){
logerr("Get xml value error,key NULL.\n");
goto RETURN_ERROR;
}
if(NULL == file){
logerr("Get xml value error,XML file NULL.\n");
goto RETURN_ERROR;
}
if(NULL == buf_out || 0 == buf_len){
logerr("buf_out invalid.\n");
goto RETURN_ERROR;
}
/*
* this initialize the library and check potential ABI mismatches
* between the version it was compiled for and the actual shared
* library used.
*/
LIBXML_TEST_VERSION
xmlTextReaderPtr reader;
int ret;
reader = xmlReaderForFile(file, NULL, 0);
if (reader != NULL) {
ret = xmlTextReaderRead(reader);//1 if the node was read successfully, 0 if there is no more nodes to read, or -1 in case of error
while (ret == 1) {
//processNode(reader);
const xmlChar *name, *value;
name = xmlTextReaderConstName(reader);
if (name != NULL && 0 == xmlStrcasecmp(name,BAD_CAST key)){
ret = xmlTextReaderRead(reader);
value = xmlTextReaderConstValue(reader);
if(NULL != value){
memcpy(buf_out,value,((size_t)xmlStrlen(value)>=buf_len?(buf_len-1):(size_t)xmlStrlen(value)));
}
break;
}
ret = xmlTextReaderRead(reader);
}
xmlFreeTextReader(reader);
if (ret == -1) {
logerr("%s : failed to parse\n", file);
}
} else {
ret = -1;
logerr("Unable to open %s\n", file);
}
/*
* Cleanup function for the XML library.
*/
xmlCleanupParser();
/*
* this is to debug memory for regression tests
*/
xmlMemoryDump();
return ret;
RETURN_ERROR:
return -1;
}
int getValueFromXMLBuffer(const char * key,const char * buffer,size_t buffer_len,unsigned char * buf_out,size_t buf_out_len){
if(NULL == key){
logerr("Get xml value error,key NULL.\n");
goto RETURN_ERROR;
}
if(NULL == buffer){
logerr("Get xml value error,XML buffer NULL.\n");
goto RETURN_ERROR;
}
if(NULL == buf_out || 0 == buf_out_len){
logerr("buf_out invalid.\n");
goto RETURN_ERROR;
}
/*
* this initialize the library and check potential ABI mismatches
* between the version it was compiled for and the actual shared
* library used.
*/
LIBXML_TEST_VERSION
xmlTextReaderPtr reader;
int ret;
//reader = xmlReaderForFile(file, NULL, 0);
reader = xmlReaderForMemory(buffer,buffer_len,NULL,NULL,0);
if (reader != NULL) {
ret = xmlTextReaderRead(reader);//1 if the node was read successfully, 0 if there is no more nodes to read, or -1 in case of error
while (ret == 1) {
//processNode(reader);
const xmlChar *name, *value;
name = xmlTextReaderConstName(reader);
if (name != NULL && 0 == xmlStrcasecmp(name,BAD_CAST key)){
ret = xmlTextReaderRead(reader);
value = xmlTextReaderConstValue(reader);
if(NULL != value){
memcpy(buf_out,value,((size_t)xmlStrlen(value)>=buf_out_len?(buf_out_len-1):(size_t)xmlStrlen(value)));
}
break;
}
ret = xmlTextReaderRead(reader);
}
xmlFreeTextReader(reader);
if (ret == -1) {
logerr("failed to parse buffer\n");
}
} else {
ret = -1;
logerr("Unable to read from buffer\n");
}
/*
* Cleanup function for the XML library.
*/
xmlCleanupParser();
/*
* this is to debug memory for regression tests
*/
xmlMemoryDump();
return ret;
RETURN_ERROR:
return -1;
}
main.c
因为只是做简单的测试,这里就剩了各种判断了。
函数返回值表明成功与否,结果存在参数传入的buf里。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "logger.h"
int main(int argc,char** argv){
init_log(3);
char buf[1024]={0};
getValueFromXMLFile("gjob:Category","gjobs.xml",buf,sizeof buf);
printf("%s",buf);
release_log();
return 0;
}
编译的时候加了-lpthread是因为我logger.c代码里用了线程:
gcc -g main.c getXmlValue.c -lxml2 -I/usr/local/include/libxml2 logger.c -lpthread
[penggl@localhost example]$ ./a.out gjobs.xml
./a.out: /usr/lib64/libxml2.so.2: no version information available (required by ./a.out)
./a.out: /usr/lib64/libxml2.so.2: no version information available (required by ./a.out)
Log process run.
Warning: program compiled against libxml 209 using older 206
key:gjob:Category value:Development
waiting for child exit...
[penggl@localhost example]$
程序执行正常,但出现这两行,说版本不对,还要找找相关信息。
./a.out: /usr/lib64/libxml2.so.2: no version information available (required by ./a.out)./a.out: /usr/lib64/libxml2.so.2: no version information available (required by ./a.out)
PS:版本不对,ldd了下/usr/lib64/libxml2.so.2指向同目录下的/usr/lib64/libxml2.so.2.6.26
把软链接删除,重新建立到新版本的so就可以了ln -s /usr/local/lib/libxml2.so.2.9.1 /usr/lib64/libxml2.so.2